Supported hardware as of this writing (2016-09-16):

  1. YubiKey 4
  2. YubiKey 4 Nano
  3. YubiKey Neo

See YubiKey Hardware Comparison for more information.

YubiKey OpenPGP Support

Several YubiKey devices have an OpenPGP engine that may be used for a number of useful purposes including:

  1. Document signing
  2. Document encryption
  3. User authentication

The third case is the basis for SSH key-based host access using an authentication key stored on the device. Compatible YubiKeys support a couple of notable standards:

  1. OpenPGP Card - OpenPGP + smart card
  2. NIST SP 800-73 - Personal Identity Verification

There are a couple notable security characteristics of these YubiKeys that provide additional security over file-based keys:

  1. Private keys and passwords cannot be read from the card with any command or function. (OpenPGP Card 2, §5)
  2. Private key operations using the authentication key require the PIN to be submitted and verified. (800-73, §3.1.3)

Thus the YubiKey 4 is naturally a 2-factor authentication device for SSH host key-based access.

HOWTO Configure a YubiKey for SSH Host-Based Access

Because of robust standards support a number of tools may be used to provision, manage, and interact with the device. The following sections describe the process to provision a YubiKey 4 for general use as an OpenPGP key store followed by additional steps for SSH key-based hostbased access. The following instructions discuss GNU Privacy Guard (gpg) for OpenPGP support, but any software that supports the OpenPGP standard should work.

Provision PGP Keys

Follow the instructions on the following page to generate PGP keys on a YubiKey.

HOWTO Import PGP Keys onto a YubiKey

The recommended approach creates standard file-based PGP keys that are subsequently imported onto the device. Note that the ephemeral file-based keys are destroyed in the process of importing.

Configure Identity and Security

The following configuration items on the YubiKey should be configured as a matter of best practices:

  1. Signature PIN
  2. Administrator PIN
  3. Login data (PID)
  4. Name of Cardholder (givenName sn)

The following code excerpt shows a terminal session where the above items are configured. Interstitial comments help identify what’s happening and where user data is required.

marvin@eiger:~/Code/middleware-www$ gpg --card-edit

Application ID ...: D2760001240102010006046387270000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 04638727
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: serac
Signature PIN ....: not forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> passwd
#=============================================
# Middleware Hint
# Type the default PIN, 123456
# The new PIN must be at least 6 digits
#=============================================
gpg: OpenPGP card no. D2760001240102010006046387270000 detected
PIN changed.

gpg/card> admin
#=============================================
# Middleware Hint
# You are now in elevated administrator mode
#=============================================
Admin commands are allowed

gpg/card> passwd
#=============================================
# Middleware Hint
# Type the default admin PIN, 12345678
# The new PIN must be at least 8 digits
#=============================================
gpg: OpenPGP card no. D2760001240102010006046387270000 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 3
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? q
gpg/card> login
Login data (account name): [your pid]
#=============================================
# Middleware Hint
# Type your PID then [enter]
# You will be prompted for the admin PIN
#=============================================

gpg/card> name
Cardholder's surname: [your last name]
Cardholder's given name: [your first name]

gpg/card> quit

You may configure other identity items on the card, but the above are the minimum recommended.

Configure SSH Agent Support

The gpg-agent program is a part of GNUPG and provides an ssh-agent emulation mode that may be used for SSH key management. When gpg-agent is successfully configured, ssh-add will report the authentication key on the YubiKey:

marvin@eiger:~/Code/middleware-www$ ssh-add -L
error fetching identities for protocol 1: agent refused operation
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCYajMYaW2RJJo2Dl67CPhCJRIWWuMt9TsHxAwfR72nnIZZ7sXdM5FT8d1C0A6BL3oQzDrtRUAVyyWRwkj9DemHDlct4DbK0dQ26FD8THd3areJsEfkoXCH2z03obkfAWzpxDqMUOwtppnq3OoRtkBuXIuR7LRrS5tPsuqnDFzm2O7D3qHrTprudM6/x6E1jXwRzEpAHXgPFc6eyVHeCLDrYHdkHFskRUAuCsWxxNq9ZabtqhyNFFG1JpwWoN2pSgjEuc5qbXR2wKkE/B8/mlTGeMlRiint5RAGQ4Xm09d8/I6OQIaY5pbyFyE3C3/g7KbTOGUjDF3jco3noI0nLROhNMIRXcF9QRidGxMkcE4cE0cWWm3Z1keI3sKDD8AeFmXaB1ToekKA7tMub0a1AXC91uErmlvMgwdd52UNYNJrRLKbI227C7K3u8I37pzfp0rWuBCsH9bhVsamztkgMksnbVPNgC7XT8lT1khemwvO3eg2LN3durMPH0LfZCAywQAId18bYOpt+Vn25xceJWbeoQHwCAoixHUcVZQag7Kgjv54WTxMmbqrxRF98UhzQtbzsESbVIGtOtOiEz7yGFdahPSkra5FSE2rSBB09EgkCYmRTMH1dNVwHHA9rRnDiC2p1RtTYc19k2B+B8E2XoAaZ+lH5HHCDMdKV8EfGVhyEw== cardno:000604146493
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDAETNp7ICqR6hTyqakkXJGbeJMzQb3jpQDEDk3q3MTKfXjEkAFV44xQvXaJyyhG2C2xLihi2an4i8ybnCwc91nOp0zN0piFgKBHzeuQUGF0rlC5zoy7gRcyMliNivY5dBgG5LeaV69hYIGPNRe2hTQFbR+mhprofSXwwGSmg3/QmTP+3cq4L8rOizAbO2WFoUwLhCHHARSgAsnTOWeu7oldP6qKd/piYowvsTEU25ZtPFd1Fd1QRceVfESmMCIq998TtVPka567Em6DfVNOk4nqipmJDwdN9bS93+Xbo8zbRT1wyArHOEYE5hiarDiV1SzX6PD+khp+C+37SCw2HTpaMOMyGKdHytihMR456IKDJzaQGSxc5fyPSU8Ql1z3CtfT3b5XBOLGh17vsyaR6UdDfgrI35ZQDMMGTJy9uZ8rFKJjyD9hBQ3QCFf2cSdggkcc6Fc74/U2rrmTzUKpMBlB3Kbu14SzrH93D2eN42n0xG7icMllywqeTWiNTNQNjgyxVeViC6lOI+l+m/CxIN/ZMCE4gk37+8VMop8Zkd0HWnzj5I8PTNOjSIYkqBp7zYZhVy9nSUbZDyjHDWhEbjp4xP/dKyZ6BQMuu7/GkjDCu5uklRA5FoWZOhz+VAo2vFvvoFzmJBtMYcT3KDTIfKUylyGtRFkQIXlNEQKxHPm/w== /Users/marvin/.ssh/id_rsa

The following instructions assume a Unix-oriented environment and have been tested and used productively on OSX.

Ensure that the file ~/.gnupg/gpg-agent.conf contains the following lines:

enable-ssh-support
write-env-file
use-standard-socket

Create the file if necessary. Next add the following script to your ~/.bash_profile:

# GPG SSH agent emulation for SSH key auth with PGP keys
AGENT_INFO="${TMPDIR}.gpg-agent-info"
function restart_gpg_agent {
  pkill gpg-agent
  eval $(gpg-agent --daemon --write-env-file "$AGENT_INFO")
}
if [ -z $(pidof gpg-agent) ]; then
  restart_gpg_agent
else
  source "$AGENT_INFO"
  export GPG_AGENT_INFO
  export SSH_AUTH_SOCK
  export SSH_AGENT_PID
fi

The use of a Bash function is helpful to provide a quick and easy way to restart gpg-agent if it dies or becomes unresponsive, which has been noted in daily use. Usually typing restart_gpg_agent a few times until ssh-add -L displays your authentication key is sufficient to restore a hung or dead gpg-agent.

Once the script above is in place, open a new shell and verify that your YubiKey authentication key is listed in the output of ssh-add -L. Do not proceed until that condition is met. Save off your public key to a file and upload it to the hosts to which you wish to authenticate via SSH key-based auth:

ssh-add -L 2>/dev/null | head -n1 > $TMPDIR/yubikey.pub
ssh-copy-id -i $TMPDIR/yubikey.pub some host.vt.edu

Repeat the ssh-copy-id command for as many hosts as you want to access with your YubiKey.