Simple file encryption using PGP cards (e.g. Yubikeys)
Project description
Cryptie: Simple PGP-compatible public-key file encryption
This repository contains a simple tool for encrypting and decrypting files using OpenPGP-based public key cryptography and (optionally) compatible 'smart cards' (e.g. Yubikeys), without the complexity of using PGP directly.
This tool is limited to the following simple operations:
- Creating key pairs on a PGP smart card or in software
- Encrypting data using a public key
- Decrypting data using private key (which may reside on a PGP smart card)
Nothing more, nothing less.
Whilst cryptie happens to use GnuPG/PGP internally, it does not attempt to be a "simpler interface to all of PGP". Cryptie's primary use case is to provide a secure, yet easy to use, way to perform PGP-compatible public key based encryption and decryption. For example, you might use it to complement Hashicorp Vault's PGP unseal key encryption feature.
Installation
Cryptie can be installed directly from its repository using pip, e.g.:
$ pip install cryptie
Cryptie relies on GnuPG to do what it needs to do.
On Debian-alike-distributions:
Install GnuPG and Smart Card Daemon (scdaemon) for Yubikey support:
$ sudo apt install gnupg scdaemon
On MacOS:
Install GnuPG and the graphical pinentry-mac PIN entry tool:
$ brew install gpg pinentry-mac
Add the following line to /usr/local/etc/gnupg/gpg-agent.conf (create it if
it doesn't exist):
pinentry-program /usr/local/bin/pinentry-mac
This configures GnuPG to use the graphical pinentry-mac tool for obtaining
PINs (rather than the terminal, which may not be available e.g. within
Ansible).
Usage
Setting up PGP smart cards (e.g. Yubikey)
Generating keypairs on a PGP smart card
To generate a new keypair on a fresh smart card (e.g. Yubikey):
$ cryptie init-card public_key.gpg "Your Name"
You will be prompted to enter the user PIN and admin PIN for the card several times.
Tip: All PGP smart cards (including Yubikeys) are factory-programmed with a user PIN of 123456 and an admin PIN of 12345678.
Tip: Yubikeys can be factory reset (permentantly deleting any private keys, and setting the PINs to default) using
ykman openpgp reset.Note: PGP smart cards only have capacity for a single key pair.
The generated public key is written to public_key.pgp (in this example) and
the private key (irretrivably) resides in the smart card.
Warning: The public key is not stored on the card and, if lost is not easily recovered and you will not be able to use the private key without it.
Changing PGP smart card PINs
You can (and should!) change the user and admin PINs from their defaults using:
$ cryptie change-pin --user
$ cryptie change-pin --admin
Tip: The user PIN is needed whenever you wish to decrypt something. If you mistype it three times in a row, the card will become locked. It can be reset again using the admin PIN. The admin PIN is otherwise only used during card configuration.
Since either PIN is enough to decrypt data (either directly or as a way to reset the user PIN), you should make sure both are chosen securely. You may choose to set both PINs to the same value.
Setting up software-based keypairs
Generating keypairs in software
To generate a new keypair in software (i.e. not on a smart card):
$ cryptie init-keypair public_key.gpg private_key.gpg "Your Name"
You will be prompted to enter a passphrase for the keypair several times.
Changing private key passphrases
To change the passphrase used to encrypt a software (i.e. non-smart card) private key, use:
$ cryptie change-passphrase private_key.gpg
You will be prompted to enter the old and new passphrases several times. By default the private key file will be overwritten with the newly encrypted private key.
Encrypting data
You can encrypt some data with a public key like so (card not required):
$ cryptie encrypt public_key.gpg < plaintext.txt > ciphertext.bin
You can decrypt the data again by providing the public key used to encrypt it and inserting the card holding the private key:
Decrypting data
To decrypt data using a private key held in a file (i.e. not on a smart card):
$ cryptie decrypt private_key.gpg < ciphertext.bin > decrypted.txt
To decrypt data using a private key held on a PGP smart card (e.g. Yubikey):
$ cryptie decrypt public_key.gpg < ciphertext.bin > decrypted.txt
Note: The need to supply the public key is an unfortunate quirk of PGP and GnuPG.
Showing metadata
In addition to the basic operations above, a pair of commands are also provided for printing information about public keys and cards:
$ cryptie card-info
Card Serial: 12345678
Key fingerprint: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
$ cryptie key-info publick_key.gpg
Type: public key
User ID: John Doe (card serial 12345678) <john@example.com>
Fingerprint: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Key ID: BBBBBBBBBBBBBBBB
Tip: By default, the card serial used to generate a keypair on a smart card is included in the user ID comment field.
For further details, see --help.
Troubleshooting card-not-found issues
If your card isn't being detected for some reason, it may be that some component of GnuPG has got into a bad state and is holding onto the card. You can use the following to try and unstick it.
Gracefully kill any running gpg-agent (this is usually done automatically by Cryptie).
$ gpgconf --kill gpg-agent
In case there's some other gpg-agent in some long-lost GNUPGHOME still running, you can use:
$ killall gpg-agent
The card is actually interacted with via the scdaemon agent (controlled by gpg-agent). Though this usually shuts down with gpg-agent, you can try killing it manually:
$ killall scdaemon
If you happen to have pcscd installed, this can also sometimes interfere with card access. You can try restarting it to release control of any cards it has grabbed.
$ sudo systemctl restart pcscd
Troubleshooting other odd errors
This tool acts as a wrapper around GnuPG. Whilst it only uses documented, stable and explicitly machine-accessible interfaces, GnuPG is still primarily designed as an interactive tool. As such, it is possible that changes to GnuPG could cause issues to this tool.
Inserting -vv (two verbose flags) before the subcommand name will cause this
tool to print out every command it runs as well as displaying all GnuPG output.
This may help reveal what might be going on. In this mode, messages produced by
cryptie are prefixed with ###.
Take a look at INTERNALS.md for a beginners overview of the
relevant parts of GnuPG and a description of what this tool does and how to
perform all of the necessary steps manually if needed. Likewise, see the
docstrings at the top of the files in the gpg submodule
for more information.
Development
To run the test suite:
$ pip install -r requirements-test.txt
$ pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cryptie-0.0.2.tar.gz.
File metadata
- Download URL: cryptie-0.0.2.tar.gz
- Upload date:
- Size: 38.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2af7e75c804af79441eab7e717920e8919f3c3f97168a5ed10bc53bd79c7922
|
|
| MD5 |
68476e1e24ef1cd9b3288943c470ca49
|
|
| BLAKE2b-256 |
7d97c105a946c88548bf4714d5c227e5eb23e9cc5a48d2b0d0f163f8ab0bf526
|
Provenance
The following attestation bundles were made for cryptie-0.0.2.tar.gz:
Publisher:
release.yml on bbc/cryptie
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cryptie-0.0.2.tar.gz -
Subject digest:
e2af7e75c804af79441eab7e717920e8919f3c3f97168a5ed10bc53bd79c7922 - Sigstore transparency entry: 319543233
- Sigstore integration time:
-
Permalink:
bbc/cryptie@d4cd78d6a275fdca2891e8b099df279318aa7ec9 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/bbc
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d4cd78d6a275fdca2891e8b099df279318aa7ec9 -
Trigger Event:
release
-
Statement type:
File details
Details for the file cryptie-0.0.2-py3-none-any.whl.
File metadata
- Download URL: cryptie-0.0.2-py3-none-any.whl
- Upload date:
- Size: 39.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8855b2a52615d496a72ce72bc6beceece4833be87ff1181e36157e836e5df29
|
|
| MD5 |
5f83c727b49311facb269f513aa3cce8
|
|
| BLAKE2b-256 |
841523466e10b8be7138def9bab933fc9124c21e1146234f604e208281b3fcfd
|
Provenance
The following attestation bundles were made for cryptie-0.0.2-py3-none-any.whl:
Publisher:
release.yml on bbc/cryptie
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cryptie-0.0.2-py3-none-any.whl -
Subject digest:
f8855b2a52615d496a72ce72bc6beceece4833be87ff1181e36157e836e5df29 - Sigstore transparency entry: 319543246
- Sigstore integration time:
-
Permalink:
bbc/cryptie@d4cd78d6a275fdca2891e8b099df279318aa7ec9 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/bbc
-
Access:
internal
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d4cd78d6a275fdca2891e8b099df279318aa7ec9 -
Trigger Event:
release
-
Statement type: