Using SSH User Certificates with PIV keys

This is a step-by-step on how to setup SSH user certificates using PIV for hardware-backed keys. This guide is primarily for an OS X or Linux system.

Prerequisites

  • a YubiKey with the PIV application loaded

  • the yubico-piv-tool software

  • the ykcs11 PKCS#11 module

  • OpenSSH

Note
This has been tested as working with OpenSSH version 7.2p2. It has also been tested as not working with OpenSSH version 6.9p1.

Steps

  1. Generate an "ssh user CA" key and trust it for this account on this host

    ssh-keygen -N '' -C user-ca -f ~/.ssh/ca
    sed 's/^/cert-authority /' ~/.ssh/ca.pub > ~/.ssh/authorized_keys
    
  2. Generate a key in PIV slot 9c that requires touch. (Note the second operation will require touch)

    yubico-piv-tool -a generate -s 9c -A RSA2048 --pin-policy=never --touch-policy=always -o public.pem
    yubico-piv-tool -a selfsign-certificate -s 9c -S "/CN=SSH key/" -i public.pem -o cert.pem
    yubico-piv-tool -a import-certificate -s 9c -i cert.pem
    
  3. Double check that the key appears in slot 9c (optional)

    yubico-piv-tool -a status
    
  4. Clear the SSH agent

    ssh-add -D
    ssh-add -e /PATH/TO/libykcs11.so
    
    • Make sure to use the correct path (e.g. /usr/local/lib) and extension (.so for Linux, .dylib for Mac OS X) for libykcs11.

    • Beware that ssh-add -D doesn’t seem to clear PKCS#11 libraries, only keys (link).

  5. Add PIV to the SSH agent (will prompt for PIV PIN)

    ssh-add -s /PATH/TO/libykcs11.so
    
  6. Get the public key from PIV and sign it using the CA key. This produces ~/.ssh/id_rsa-cert.pub

    ssh-add -L > ~/.ssh/id_rsa.pub
    ssh-keygen -s ~/.ssh/ca -I identity -n "${LOGNAME}" ~/.ssh/id_rsa.pub
    
  7. Authenticate to the target system using the new key:

    ssh user@remote.example.com
    

If you have followed these steps to the letter, you will not be asked for the PIV PIN, but your YubiKey will start blinking, waiting for touch.

More info

For more information see the CERTIFICATES section of ssh-keygen(1).

Thanks

Thanks to Christopher Harrell and Dean Sutherland from the Yahoo Paranoids for providing the instruction and the testing.