Using PIV for SSH through PKCS11

This is a step-by-step for how to get a YubiKey with PIV to work for public-key authentication with OpenSSH through PKCS11. Primarily on a OS X or Linux system.


  • a YubiKey with the PIV application loaded

  • the yubico-piv-tool software

  • the OpenSC software

  • OpenSSH

    • If you are using OSX El Capitan (10.11) or earlier, for ssh-agent to work a newer OpenSSH than is delivered with the system; macOS Sierra (10.12) contains a compatible version

The following example assume that you have not yet changed the management key. If you have changed the management key, add --key to the yubico-piv-tool -a import-certificate command below.


  1. Generate a key in slot 9a (any slot should suffice):

    yubico-piv-tool -s 9a -a generate -o public.pem
    RSA 4096-bit keys are not currently supported due to a limitation in the PIV spec:
  2. Create a self-signed certificate for that key. The only use for the X.509 certificate is to make PIV/PKCS#11 lib happy. They would want to be able to extract the public-key from the smartcard, and do that through the X.509 certificate.

    yubico-piv-tool -a verify-pin -a selfsign-certificate -s 9a -S "/CN=SSH key/" -i public.pem -o cert.pem
  3. Load the certificate:

    yubico-piv-tool -a import-certificate -s 9a -i cert.pem
  4. Find out where OpenSC has installed the pkcs11 module.

    • For OS X with binary installation this is typically in /Library/OpenSC/lib/. Homebrew users can use export OPENSC_LIBS=$(brew --prefix opensc)/lib.

    • For a Debian based system this is typically in /usr/lib/x86_64-linux-gnu/

      After this we’ll call this location $OPENSC_LIBS

  5. Export the public key in correct format for ssh and once you got it, add it to authorized_keys on the target system.

    ssh-keygen -D $OPENSC_LIBS/ -e
    The command will export all keys stored on the YubiKey Neo. Hopefully it will keep the slot order so it should be not hard to guess which is the public key associated with your targeted private key.
  6. Authenticate to the target system using the new key:

    ssh -I $OPENSC_LIBS/
  7. This can also be setup to work with ssh-agent: (Optional)

    ssh-add -s $OPENSC_LIBS/
    On OS X prior to macOS 10.12 “Sierra” this typically requires installation of a third-party OpenSSH from Homebrew or the like and using that ssh-agent.

    To confirm that the ssh-agent correctly finds that key and getting the public key in correct format:

    ssh-add -L