str4d / age-plugin-yubikey

YubiKey plugin for age
Apache License 2.0
561 stars 26 forks source link

Native age identity support #174

Open str4d opened 4 months ago

str4d commented 4 months ago

YubiKeys with firmware 5.7.0 and above have support for X25519 (thanks https://github.com/smlx/piv-agent/issues/134 for making me aware of this).

It should be possible to generate native age identities in PIV slots, and use them just like P-256 identities on the decryption side (our identity format points to a specific YubiKey serial and slot, from which we can then determine whether or not the key is P-256 or X25519). On the encryption side, these would just be regular native age recipients (and thus not require a plugin to encrypt to).

The downside is that because native age identities do not include any sort of tag, we would need to assume that any X25519 YubiKey slot could potentially match, which means in multi-key settings the UX is not as great, but that is a trade-off we can probably explain in the setup TUI.

pinpox commented 4 months ago

Would this allow for using existing age (or ssh) keys on the yubikey? I"m searching for a solution that let's me use the yubikey for age encryption/decryption while having a offline (printed out) backup of my key so that I can restore it on a new yubikey in case of I lose it.

dlubawy commented 1 month ago

This is definitely possible. I created a PR over at yubikey.rs to add curve 25519 support to the underlying yubikey crate. I then forked this repo on a new branch to test it all out together. It seems to work alright (though the code isn't great since I'm still new to Rust).

Some things to consider:

I made a Python script to convert age identities to key/cert PEM files for upload to a YubiKey which can then be used with the branch I made.

Additionally, I tested using native keys in the original format on another branch and it's definitely doable with the same caveat listed above. It has the exact problem that was described whereby the identities and recipients won't match due to a tag not being included within native age. I had to assume all YubiKey slots could match when no tag was included in the RecipientLine. This means one has to touch the key 'N = Slot Number'. Not the best UX.

pinpox commented 4 days ago

@str4d Would you be interested/have the time to implement this? If it's just having a new yubi that's missing for this, I would offer to sponsor one.