This age plugin lets you reuse your OpenPGP Card devices (such as Yubikeys or Nitrokeys) for age decryption.
Why? OpenPGP Card, contrary to its name, is just a generic cryptographic device standard. Most importantly the specification and the real-world devices (e.g. Yubikeys and Nitrokeys) support curve25519.
This application is a no-moving-parts solution which requires only pcsc-lite
on Linux and reuses built-in smartcard services on Windows and macOS. No GnuPG needed, no other OpenPGP software is used or accessed.
If you don't need curve25519 and are using Yubikeys then the age-plugin-yubikey
provides a more polished experience.
This plugin assumes that you have already provisioned the card.
oct admin generate
may be used to provision the card with a new curve25519 key.
(This is actually how end-to-end tests are implemented. See scripts/encrypt-and-decrypt.sh
).
At this moment the installation from crates.io
is the only supported method:
cargo install --locked age-plugin-openpgp-card
Running the tool directly outputs the public keys and the identity stubs for all connected cards:
$ age-plugin-openpgp-card | tee identity.txt
# Card ident 0006:15422467
# age1dkfzfyk58yvkf07n32nygkyuqxtnq2am427sy79gjkh6krf96frsucn0me
AGE-PLUGIN-OPENPGP-CARD-1XQCRQD36XY6NGV3JXSMRWAN88PC
Note that the public key looks like a regular age ed25519 key. The stub encodes the card identifier and is mostly irrelevant. If the stub is lost it may be regenerated - if the key on the card is the same the decryption will succeed.
Any age-compatible tool can be used for encryption:
$ echo I like strawberries | age -r age1dkfzfyk58yvkf07n32nygkyuqxtnq2am427sy79gjkh6krf96frsucn0me -a > encrypted.age
And the identity stubs are required for decryption:
$ age -d -i identity.txt < encrypted.age
I like strawberries
The plugin will ask you for the PIN using built-in plugin protocol (e.g. rage
would show a pin-entry prompt).
This repository contains end-to-end integration tests which run a virtual Nitrokey card, provision it with a new key and then encrypt and decrypt data using rage
.
The plugin is basically glue code for already existing, awesome libraries and tools:
openpgp-card
which interacts with the smartcards,age-plugin
which provides easy to use framework for writing age plugins,
And, last but not least, opcard
which provides us with a virtual card to test that all of this really works!
Thank you very much for all contributors to these projects 🙇♂️
This project is licensed under either of:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.