-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FR: Put the same age key on multiple Yubikeys #75
Comments
This will list all identities for plugged in YubiKeys: $ age-plugin-yubikey --identity > identities You can then encrypt to multiple identities: $ identities=$(cat identities | grep Recipient | sed -e "s/ //g" | cut -d':' -f2 | sed -e 's/^age\(.*\)/ -r age\1/g' | tr -d '\n')
$ rage $identities -e input.file -o output.file.age Then decrypt to a single identitiy (a single plugged in YubiKey): $ age-plugin-yubikey --identity > identity 2>/dev/null
$ cat $secret_file | rage -d -i identity Have a look at how I've done it in pass for more details. |
BTW: the actual keys stored on the Yubikeys are still different^. |
ok, so you mean private age keys should be different and I should encrypt to all of them, which in fact makes this topic closable. thanks for the heads up. :) |
I am interested in the same thing for the same reason. I'd prefer having the same secret key on all my YubiKeys, so that if I have to replace one, I don't have to go around re-encrypting everything. I understand the tradeoffs involved and I understand why people prefer to have separate private keys per hardware token. But I'd like the option to use an offline generated key. |
My 2 cents: I understand your point. Not sure if it's technically possible. I believe a Yubikey-unique part (possibly hardware-coded) is involved in the process of generating an identity. It is therefore unique and if you lose the Yubikey, you are left with whatever others you used to encrypt. Would like it if somebody could confirm/refute this^. |
I usually put my gpg identity on two different yubikeys, as stated for backup reasons. So I thought this should be possible with age keys also. |
@str4d ? |
Another way to achieve this would be by generating the private key on an "unsafe device" and then importing it to the YubiKey(s). Is there a way/tutorial how to import private keys to the Yubikey? |
@kmille It's easy to do that using |
Is there a technical reason/limitation behind this or could that be changed on I would love to move from gpg to age for all encrypting purpouses, is there any chance we could allow keys not generated on the yubikey itself and copied via ykman? This would also solve #3 |
@mihaigalos I have a key and can help test this but need some guidance. How do you generate a key in the correct format to be imported? @Merovius how did you generate your key? |
I'm not sure how to import that key. I generated one like shown in the screenshot and saved the two strings to files:
I then tried to import them into my testing yubikey:
I suppose that is not the correct format that I also have tried removing the spaces. |
I found some information regarding this. Citing from: https://smallstep.com/blog/access-your-homelab-anywhere/
Could this be the cause? |
I don't quite get how you get from |
You can generate a private key with a tool of your choice, for example:
You can then import it into an arbitrary slot of your YubiKey using
Going from there to actually getting So I'd expect The documentation implies that only the retired key slots are used. But even if I store a private key into slot |
My Rust skills are limited at best but as far as I can see, there is a certificate check whenever a key is read from a slot. So I guess (emphasis on GUESS) is that keys generated with age-plugin-yubikey are signed or identified with a certeain certificate, in order to make sure this is not a key used by any other PIV service. |
@str4d Can you confirm this? If true, would you be able to make that optional or disable it alltogether so we can use exteranally generated age keys? |
did you guys try this... $ openssl ecparam -name prime256v1 -genkey -noout -out test0001.key.pem
$ openssl req -new -key test0001.key.pem -x509 -nodes -out test0001.cert.pem -days 3650 -subj "/CN=age identity test0001/OU=0.5.0/O=age-plugin-yubikey"
$ ykman piv certificates import 82 --pin-policy ALWAYS --touch-policy CACHED test0001.cert.pem
Enter PIN:
Certificate imported into slot RETIRED1
$ ykman piv keys import 82 test0001.key.pem
Enter PIN:
Private key imported into slot RETIRED1. $ age-plugin-yubikey -l
# Serial: 11451419, Slot: 1
# Name: age identity test0001
# Created: Thu, 1 Jan 1970 00:00:00 +0000
# PIN policy: Unknown (yes it's unknown here)
# Touch policy: Unknown (also unknown)
*HERE IS THE RECIPIENT*
$ age-plugin-yubikey --identity --slot 1 > ident
Recipient: *HERE IS THE RECIPIENT*
$ RECIPIENT='*HERE IS THE RECIPIENT*'
$ echo foobar | rage -e -r $RECIPIENT | rage -d -i ident
foobar |
Move further: write this to [ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_age-plugin-yubikey
prompt = no
[ req_distinguished_name ]
0.organizationName = age-plugin-yubikey
organizationalUnitName = 0.5.0
commonName = age identity test0001
[ v3_age-plugin-yubikey ]
subjectKeyIdentifier = none
1.3.6.1.4.1.41482.3.8 = DER:0101
# PinPolicy::Default => 0,
# PinPolicy::Never => 1,
# PinPolicy::Once => 2,
# PinPolicy::Always => 3,
# TouchPolicy::Default => 0,
# TouchPolicy::Never => 1,
# TouchPolicy::Always => 2,
# TouchPolicy::Cached => 3, Where the 2nd bit of openssl req -config age.cnf -new -key test0001.key.pem -out test0001.csr
openssl x509 -req -sha256 -days 3650 -in test0001.crt -signkey test0001.key.pem -out test0001.cert.pem Note: Use And import it, then check the output of ykman piv certificates import 82 test0001.cert.pem
ykman piv keys import 82 --pin-policy NEVER --touch-policy ALWAYS test0001.key.pem $ age-plugin-yubikey -l
# Serial: 11451419, Slot: 1
# Name: age identity test0001
# Created: Thu, 1 Jan 1970 00:00:00 +0000
# PIN policy: Never (A PIN is NOT required to decrypt)
# Touch policy: Always (A physical touch is required for every decryption)
age1yubikey1blahblahblahblah Yes, I may write a simple |
Had to do some adaptations from #75 (comment) because the $ cat age-plugin-yubikey.cnf
[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[ req_distinguished_name ]
0.organizationName = age-plugin-yubikey
organizationalUnitName = 0.5.0
commonName = something something (age)
[ v3_req ]
subjectKeyIdentifier = hash
1.3.6.1.4.1.41482.3.8 = DER:0101
# PinPolicy::Default => 0,
# PinPolicy::Never => 1,
# PinPolicy::Once => 2,
# PinPolicy::Always => 3,
# TouchPolicy::Default => 0,
# TouchPolicy::Never => 1,
# TouchPolicy::Always => 2,
# TouchPolicy::Cached => 3, $ cat build.sh
#!/bin/bash
set -o errexit
CNF="age-plugin-yubikey.cnf"
KEY="age.key.pem"
CRT="age.cert.pem"
CSR="age.csr"
PIN="123456"
SERIAL="99999999"
# DONT OVERWRITE KEY
# openssl ecparam -name prime256v1 -genkey -noout -out $KEY
openssl req -config $CNF -new -key $KEY -out $CSR
openssl x509 -req -sha256 -days 3650 -in $CSR -signkey $KEY -out $CRT -extfile $CNF -extensions v3_req
openssl x509 -in $CRT -text -certopt ext_dump -noout
ykman piv certificates import 82 $CRT --pin $PIN
ykman piv keys import 82 --pin-policy NEVER --touch-policy NEVER $KEY --pin $PIN
age-plugin-yubikey -l
age-plugin-yubikey -i --serial $SERIAL --slot 1 > age-identity.txt
cat foo.txt.age | age -d -i age-identity.txt |
For backup reasons I would like to be able to put an age private key on more than one Yubikey so in case one Yubikey breaks, gets lost, is unusable in some other way, I would have another key that could decrypt my files. I might have overlooked such a feature, if so, please let me know how to do it.
The text was updated successfully, but these errors were encountered: