Edit 2023-03-03: This is now written in long-form at https://jamesog.net/2023/03/03/yubikey-as-an-ssh-certificate-authority/
The original version is retained below.
ykman
from theyubikey-manager
package- libykcs11 from the
yubico-piv-tool
package
- Get a YubiKey to act as a dedicated CA - this key should not be used for other purposes
- Generate a certificate on the CA key
- Obtain the public key for the CA
- Collect SSH public keys to be signed
- Sign them!
This is mostly necessary if you use multiple YubiKeys. You can skip this if you only have the CA key.
ykman list
Check the PIV info of the device you want to use
ykman --device <serial from above> piv info
(You can skip the --device
flag if you only have one key.)
Assuming this is a brand new key, change the management key, PIN and PUK from the default values.
ykman --device <serial> piv change-management-key --touch --generate
Ref. https://developers.yubico.com/yubikey-piv-manager/PIN_and_Management_Key.html for PIN limitations
You can use pwgen
to generate a secure PIN, e.g.
pwgen -sy 8 1
Change the PIN and PUK. 123456 / 12345678 are the default values, respectively.
ykman --device <serial> piv change-pin -P 123456
ykman --device <serial> piv change-puk -p 12345678
We only need CCID mode on the CA YubiKey, OTP and FIDO won't be used, so let's disable them.
% ykman --device <serial> mode CCID
Set mode of YubiKey to CCID? [y/N]: y
(N.B. I had to reinsert the YubiKey after doing this, otherwise ykman generated a traceback with error ykman.driver_ccid.CCIDError: Failed to transmit with protocol T1. Card was reset.
during the next step.)
Create a private key. We'll use slot 9d.
Ref. https://developers.yubico.com/PIV/Introduction/Certificate_slots.html
% ykman --device <serial> piv generate-key 9d ca.pem
Enter a management key [blank to use default key]:
Touch your YubiKey...
And now generate a certificate whose subject is "SSH CA" and is valid for ~10 years. This outputs the public key to ca.pem
.
% ykman --device <serial> piv generate-certificate -s "SSH CA" -d 3650 9d ca.pem
Enter PIN:
Enter a management key [blank to use default key]:
Touch your YubiKey...
At this point we have a private key and self-signed certificate on the YubiKey
% ykman --device <serial> piv info
PIV version: 5.2.6
PIN tries remaining: 3
CHUID: ...
CCC: ...
Slot 9d:
Algorithm: RSA2048
Subject DN: CN=SSH CA
Issuer DN: CN=SSH CA
Serial: ...
Fingerprint: ...
Not before: 2020-10-04 15:21:26
Not after: 2030-10-02 15:21:26
Let's get the SSH pubkey for this. We'll need a PKCS#11 library, either libykcs (provided with yubico-piv-tool) or OpenSC.
ssh-keygen -D /opt/local/lib/libykcs11.dylib
(N.B. if you have multiple YubiKeys installed this will be problematic.)
This will output two ssh-rsa keys. Take the first one and put it in a file called ca.pub
. This is used for signing.
This section is if you are using a separate YubiKey as your SSH private key.
Get the SSH pubkey for your SSH YubiKey (NOT the CA) if you don't already have it.
N.B. unplug the CA key first, otherwise you'll get both.
% ssh-keygen -D /opt/local/lib/libykcs11.dylib > yk5.pub
If you use a second YubiKey for SSH (as in the previous section), unplug that key now and ensure only the CA key is plugged in.
Sign your SSH key's pubkey. The key identity (-I
) will be your email address and we add a principle (-n
) of your SSH username.
% ssh-keygen -s ca.pub -D /opt/local/lib/libykcs11.dylib -I [email protected] -n bob yk5.pub
Enter PIN for 'YubiKey PIV #xxxxx':
Signed user key yk5-cert.pub: id "bob" serial 0 valid forever
You can inspect this with
% ssh-keygen -f yk5-cert.pub -L
yk5-cert.pub:
Type: [email protected] user certificate
Public key: RSA-CERT SHA256:Xk7dUop5/qjwucmsUduwTtG9hgBmOE/jD3UJh+wqlVY
Signing CA: RSA SHA256:TCVSthFvCaEuONOxziMLwJpdJAoY19fb4eZADw0Ovtw (using rsa-sha2-512)
Key ID: "bob"
Serial: 0
Valid: forever
Principals:
bob
Critical Options: (none)
Extensions:
permit-X11-forwarding
permit-agent-forwarding
permit-port-forwarding
permit-pty
permit-user-rc
Hi,
I'm following your tutorial on a rapsberry pi (not Mac as the
/opt/local/lib/libykcs11.dylib
path and filename suggests) and for me theyubico-piv-tool
package doesn't installlibykcs11
at all. I had to it manually from the official source.So I modified the path to generate an SSH public key:
But then I get an error message:
Therefore I can't continue the tutorial. Any suggestions?