84 lines
4.1 KiB
Markdown
84 lines
4.1 KiB
Markdown
# Age Plugin: OpenPGP Card
|
|
|
|
[](https://github.com/wiktor-k/age-plugin-openpgp-card/actions/workflows/rust.yml)
|
|
[](https://crates.io/crates/age-plugin-openpgp-card)
|
|
|
|
This age plugin lets you reuse your OpenPGP Card devices (such as [Yubikeys](https://www.yubico.com/products/yubikey-5-overview/) or [Nitrokeys](https://www.nitrokey.com/products/nitrokeys)) for [age decryption](https://age-encryption.org/).
|
|
|
|
Why? [OpenPGP Card](https://en.wikipedia.org/wiki/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](https://docs.yubico.com/hardware/yubikey/yk-tech-manual/yk5-apps.html#elliptic-curve-cryptographic-ecc-algorithms) and [Nitrokeys](https://docs.nitrokey.com/nitrokey3/faq#which-algorithms-and-maximum-key-length-are-supported)) support [curve25519](https://en.wikipedia.org/wiki/Curve25519).
|
|
|
|
This application is a no-moving-parts solution which requires only [`pcsc-lite`](https://github.com/LudovicRousseau/PCSC) 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`](https://github.com/str4d/age-plugin-yubikey) provides a more polished experience.
|
|
|
|
This plugin assumes that you have already provisioned the card.
|
|
[`oct admin generate`](https://codeberg.org/openpgp-card/openpgp-card-tools/#generate-keys-on-the-card) 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`).
|
|
|
|
## Installation
|
|
|
|
At this moment the installation from `crates.io` is the only supported method:
|
|
|
|
```sh
|
|
cargo install --locked age-plugin-openpgp-card
|
|
```
|
|
|
|
## Usage
|
|
|
|
Running the tool directly outputs the public keys and the identity stubs for all connected cards:
|
|
|
|
```sh
|
|
$ 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:
|
|
|
|
```sh
|
|
$ echo I like strawberries | age -r age1dkfzfyk58yvkf07n32nygkyuqxtnq2am427sy79gjkh6krf96frsucn0me -a > encrypted.age
|
|
```
|
|
|
|
And the identity stubs are required for decryption:
|
|
|
|
```sh
|
|
$ 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`](https://github.com/str4d/rage) would show a pin-entry prompt).
|
|
|
|
## Tests
|
|
|
|
This repository contains end-to-end integration tests which run a [virtual Nitrokey card](https://github.com/Nitrokey/opcard-rs), provision it with a new key and then encrypt and decrypt data using `rage`.
|
|
|
|
## Thanks
|
|
|
|
The plugin is basically glue code for already existing, awesome libraries and tools:
|
|
|
|
- [`openpgp-card`](https://crates.io/crates/openpgp-card) which interacts with the smartcards,
|
|
- [`age-plugin`](https://crates.io/crates/age-plugin) which provides easy to use framework for writing age plugins,
|
|
|
|
And, last but not least, [`opcard`](https://github.com/Nitrokey/opcard-rs) 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 🙇♂️
|
|
|
|
## License
|
|
|
|
This project is licensed under either of:
|
|
|
|
- [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0),
|
|
- [MIT license](https://opensource.org/licenses/MIT).
|
|
|
|
at your option.
|
|
|
|
### Contribution
|
|
|
|
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.
|