Yubikeys
Commands for setting up a Yubikey, with GPG key, SSH key, and macOS login.
Relies on the following:
GPG
Set up roughly following this guide.
# Insert key ... duh
# Bring up gpg
$ gpg --card-edit
# Enter admin mode
gpg/card> admin
# Set the PIN and admin PIN
gpg/card> passwd
# Generate a key
gpg/card> generate
Set up the agent:
pinentry-program $PATH_TO/pinentry-mac
default-cache-ttl 600
max-cache-ttl 7200
Add the following to your profile:
GPG_TTY="$(tty)"
export GPG_TTY
gpgconf --launch gpg-agent
Seeding local instance
Import keys in RAM (e.g. /dev/shm).
$ gpg --import private.key
Export subkeys.
$ gpg --armor --output subkeys.key --export-secret-subkeys $KEY
Remove all secret keys.
$ gpg --delete-secret-keys $KEY
Re-import subkey secret keys.
$ gpg --import subkeys.key
Update the subkey to point at the Yubikey.
$ gpg --expert --edit-key $KEY
gpg> key $NUM
gpg> keytocard
Select signature key. Enter the passphrases to unlock the key, and then
enter the Yubikey admin PIN (12345678).
Save and exit.
List the secret keys, which should show a pointer to the card for the subkey.
$ gpg --list-secret-keys
------------------------------
sec> ... snip ...
ssb> ... snip ...
Shred any remaining key material.
$ shred -u $FILE [$FILE ...]
SSH
The simplest way to set up SSH with a YubiKey is using FIDO2 resident keys. This stores the private key directly on the YubiKey, with no need for PIV, OpenSC, or PKCS#11. Requires OpenSSH 8.2+ and a YubiKey with firmware 5.2.3+.
Set a FIDO2 PIN on the key if you haven't already (you'll only need to do this once):
$ ykman fido access change-pin
Generate a resident key on the YubiKey:
# The -O resident flag stores the key on the YubiKey itself, so it can
# be loaded on any machine with ssh-add -K.
# The -O application=ssh:yourname lets you distinguish multiple resident
# keys on the same YubiKey.
$ ssh-keygen -t ed25519-sk -O resident -O application=ssh:yourname
This will create ~/.ssh/id_ed25519_sk and
~/.ssh/id_ed25519_sk.pub. Add the public key to GitHub,
servers, etc.
Load the key from the YubiKey into your SSH agent:
$ ssh-add -K
Each SSH operation will require a physical touch of the YubiKey. This is a
security feature of FIDO2 and cannot be disabled when loading keys via
ssh-add -K.
Confirm the key has been added:
$ ssh-add -L
The nice thing about resident keys is portability. On a new machine, just
run ssh-add -K with the YubiKey inserted, and the key is
available immediately, with no need to copy key files around.
SSH (legacy PIV method)
Click to expand the older PIV/PKCS#11 approach
The following generates a new SSH keypair that resides on the key using PIV.
This method requires opensc and is more complex, but allows
disabling the touch requirement. Adapted from the following:
Ensure that opensc and yubico-piv-tool are
installed.
Create a volume in memory to use for temporarily storing the key material
(see ramdisk).
# Switch into the ramdisk
$ cd /volumes/secure
$ umask 077
# Create a public key.
# Enter the management key when prompted.
# Default: 010203040506070801020304050607080102030405060708
$ yubico-piv-tool \
-a generate \
-s 9a \
-k \
--pin-policy=once \
--touch-policy=always \
--algorithm=ECCP256 \
-o public.pem
# Create a self-signed certificate
# Enter the PIN when prompted, then tap the key.
$ yubico-piv-tool \
-a verify-pin \
-a selfsign-certificate \
-s 9a \
-S '/CN=ssh/' \
--valid-days=365 \
-i public.pem \
-o cert.pem
# Import the certificate
# Enter the management key when prompted.
$ yubico-piv-tool -k -a import-certificate -s 9a -i cert.pem
Confirm that the key has been added:
$ yubico-piv-tool -a status
At this point, the SSH key should be loaded on the Yubikey. Fetch the public key:
$ ssh-keygen -D $HOME/.nix-profile/lib/opensc-pkcs11.so -e
Note that the path to the .so file may differ, based on the
setup. The above is based on using Nix.
Add the key to the local ssh-agent:
$ _path=$(readlink $HOME/.nix-profile/lib/opensc-pkcs11.so) \
ssh-add -s "$_path"
Note that the path must match the value that has been whitelisted on the
ssh-agent via the -P flag.
Confirm the key has been added:
$ ssh-add -L
macOS Login
You can use the YubiKey's PIV smart card to unlock your Mac at the lock screen. This uses a certificate in PIV slot 9a (Authentication), which is separate from the FIDO2 SSH key above.
Ensure ykman is installed. Generate a key and certificate in
PIV slot 9a:
# Generate a key in the authentication slot.
$ ykman piv keys generate --algorithm ECCP256 9a public.pem
# Create a self-signed certificate (10 years to avoid frequent renewal).
# Enter the PIV PIN when prompted (default: 123456).
$ ykman piv certificates generate --subject "CN=yourname" --valid-days 3650 9a public.pem
# Clean up the public key file.
$ rm public.pem
Pair the YubiKey with your macOS user account:
# List unpaired smart card identities. Copy the hash.
$ sc_auth identities
# Pair the key with your user.
$ sudo sc_auth pair -h <hash> -u $(whoami)
Lock your screen (Ctrl+Cmd+Q) and unlock with the YubiKey by entering your PIV PIN. Set up a second YubiKey the same way as a backup.
If your PIV PIN gets blocked (3 wrong attempts), unblock it with the PUK
(default: 12345678):
$ ykman piv access unblock-pin
It's a good idea to change the default PIN, PUK, and management key:
$ ykman piv access change-pin
$ ykman piv access change-puk
$ ykman piv access change-management-key