yubico-piv-tool 1.4.0, Mac OS X 10.11.5

While you should generate your ssh keys on card or generate them on a sterile machine for escrow, you can also import an existing ssh key (usually found in ~/.ssh/id_rsa). Below is a walkthrough on how to do that. Be sure to import both the private and public side of your keypair; otherwise, ssh auth might not work. You should probably create an encrypted disk and chdir to that disk when changing the private key to pem form.

Private Key

Below, for the touch-policy, you can choose always, cached, or never. Setting it to always will require you to touch the YubiKey every time a nonce needs to be signed (every SSH connection for example). The entry of your PIN is still required unless you set --pin-policy to never. The cached touch-policy will cause the YubiKey to require you to touch it when a nonce needs to be signed, but it won't ask you to touch again for 15 seconds. Never will of course never require you to touch the YubiKey. The recommended setting for touch-policy is always or cached. If you choose never, then rogue programs can steal your PIN by watching keypresses as you enter it. Setting it to cached or always prevents this type of attack. If you are using a YubiKey NEO, then remove the --touch-policy option. The NEO does not support it yet. Only the YubiKey 4 and YubiKey 4 nano support --touch-policy as of this writing (December 2016).

[email protected]:~$ cd /Volumes/encrypted/
[email protected]:/Volumes/encrypted$ openssl rsa -in ~/.ssh/id_rsa -out id_rsa.pem -outform pem
Enter pass phrase for /Users/rchapman/.ssh/id_rsa:
writing RSA key

[email protected]:/Volumes/encrypted$ head -1 id_rsa.pem
-----BEGIN RSA PRIVATE KEY-----

[email protected]:/Volumes/encrypted$ yubico-piv-tool -a import-key --touch-policy cached -s 9a -i id_rsa.pem
Successfully imported a new private key.

[email protected]:/Volumes/encrypted$ rm id_rsa.pem

Public Key

[email protected]:/Volumes/encrypted$ ssh-keygen -e -f ~/.ssh/id_rsa.pub -m PKCS8 > id_rsa.pub.pkcs8
[email protected]:/Volumes/encrypted$ head -1 id_rsa.pub.pkcs8
-----BEGIN PUBLIC KEY-----

[email protected]:/Volumes/encrypted$ ~/bin/yubico-piv-tool -a verify -P 123456 -a selfsign-certificate -s 9a -S "/CN=joe/O=Test/" -i id_rsa.pub.pkcs8 -o 9a-cert.pem

[email protected]:/Volumes/encrypted$ ~/bin/yubico-piv-tool -a verify -P 123456 -a import-certificate -s 9a -i 9a-cert.pem ; ~/bin/yubico-piv-tool -a status
Successfully verified PIN.
Successfully imported a new certificate.
CHUID:  3019...fe00
CCC:    f015...fe00
Slot 9a:
    Algorithm:     RSA2048
    Subject DN:    CN=joe, O=Test
    Issuer DN:     CN=joe, O=Test
    Fingerprint:   cf...46
    Not Before:    Jun 20 19:13:41 2016 GMT
    Not After:     Jun 20 19:13:41 2017 GMT
[...]
PIN tries left:   15

Move .ssh/id_rsa and restart ssh-agent (otherwise it will be cached by the agent)

[email protected]:/Volumes/encrypted$ cd ~/.ssh
[email protected]:~/.ssh$ mv id_rsa ..
[email protected]:~/.ssh$ pkill ssh-agent
[email protected]:~/.ssh$ sudo launchctl start org.openbsd.ssh-agent

Set PIN and PIN Retries

You should change the user PIN as well as the PIN Unlock Code (PUK) if you have not already. The YubiKey NEO asks for the PIN every time it signs a nonce (to log you into a ssh server). If you enter the PIN wrong a number of times (3 by default), then the PIN will be locked. You can then use the PUK to unlock the PIN. If you enter the PUK wrong a number of times (again, 3 by default), then the PIV applet will bulk erase it's memory, causing your private keys and certificates to be lost. At that point, you have to reset the PIV applet and re-populate the certs and private keys.

To change the PIN and PUK retries from 3 to 15:

[email protected]:~$ unset HISTFILE
[email protected]:~$ ~/bin/yubico-piv-tool -a verify -P 123456 -a pin-retries --pin-retries 15 --puk-retries 15

Note that this step will also set the PIN and PUK codes back to factory default, so you'll need to change your PIN/PUK codes after doing this step if you already had PIN/PUK codes set.

To change the PIN and PUK:
In this example, we are changing the PIN from the default value of 123456 to 987600 and the PUK from the default of 12345678 to 98761234

[email protected]:~$ ~/bin/yubico-piv-tool -a change-pin --pin 123456 --new-pin=987600
[email protected]:~$ ~/bin/yubico-piv-tool -a change-puk --pin 12345678 --new-pin=98761234

Change the Management Key

Most security professionals would say you should change the management key as well. This is a 24 byte key which resides in slot 9B. If you forget it, you can still reset the PIV applet, which will reset the PIN, PUK, and 9B key back to defaults.

[email protected]:~$ ~/bin/yubico-piv-tool -a set-mgm-key -n 123456789012345678901234567890123456789012345678
Logout and log back in, then make sure the PIN, PUK and management key are not in ~/.bash_history

Require Touching the YubiKey for Signing

Requiring the YubiKey to be touched before it will sign a nonce improves security as it prevents a program from caching the PIN and re-presenting it. An example of a program that does this is OpenVPN with PKCS11 turned on.

Key Escrow

If you want to encrypt the private key for storage in escrow:

[email protected]:~$ cat ~/id_rsa | gpg --symmetric | base64

One place where you could store the encrypted base-64 encoded private key would be the password field of a password manager like 1Password.
To decrypt it later:

echo "base64string" | base64 -D | gpg --decrypt

Last steps

Later, when you are sure you are happy with the encrypted version of the file, remove your private key from your workstation (after all, the reason for putting your private key on a hardware token is to prevent someone from stealing it off disk).

rm ~/id_rsa id_rsa.pem