Tag Archives: smart card

SSH certificates together with hardware keys (smartcard/yubikey)

We have showed how to use SSH certificates and SSH CAs, we have also showed how you can use the yubikey to store you SSH keys. This article will describe how to combine these two features.

First of all you need to have a yubikey set up with some RSA/ECDSA keys. Then find out the public part of you key:

% ssh-keygen -D /usr/local/lib/opensc-pkcs11.so
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCHn4jSqvNLn5NtUxqlAlm1Qj1tlunb0PjBsItmmesquULAM5oqVYmwJ+bmXpDlzgeeIbl1lf3aUTsXCs6My8mkIUwwN+3a5AJ8MA18Bzzx/qIpxe2N/nZ61e03ua5B6SjpfxAAC6i3DPHU6kUSy26sXhfx14y6abWlrwhXaILsTogz2sOganS44au+nSpa35xwMxG5vehkRkYe6vQvvIDFeMhy61DAJGOcGeCbXTfJB9yYwAgOEqTvHDBfbTrHhmnUu82/JV6twY4/tdgrjFxGE3/JsRnoP3lBCoLQR+Uxs3mV7pFelQj/8bZKVsjdzqH9AYWpvIQTJGuwAmyOk61V

This public key should be handed over to your systems administratior (probably yourself in this case) for signing. In return you will get a OpenSSH certificate file that looks sort of a public key but a bit longer.

Now the “tricky” part comes. When you have your public key in ~/.ssh/id_rsa.pub ssh will automatically look for a certificate file called id_rsa-cert.pub. But since we are going to use the smartcard/yubikey to handle our key it will not be visible in ~/.ssh.

First give your certificate a reasonable name like ~/.ssh/yubikey-cert.pub. Then we could tell ssh to combine the two.

Me most basic way is then to just specify the options you need on the command line:

% ssh -o PKCS11Provider=/usr/local/lib/opensc-pkcs11.so -o CertificateFile=~/.ssh/yubikey-cert.pub peter@torus
Enter PIN for 'PIV_II (PIV Card Holder pin)': 
[torus:~] peter>

If you want to use this permanently you can of course put the options in ~/.ssh/config instead it should look something like this:

PKCS11Provider=/usr/local/lib/opensc-pkcs11.so
CertificateFile=~/.ssh/yubikey-cert.pub

A third option if you are using the ssh-agent (like me) you could first add the card to your agent:

% ssh-add -s /usr/local/lib/pkcs11/opensc-pkcs11.so
Enter passphrase for PKCS#11: 
Card added: /usr/local/lib/pkcs11/opensc-pkcs11.so

and the specify the cert-file either on the command line or in ~/.ssh/config

% ssh -o CertificateFile=~/.ssh/yubikey-cert.pub peter@torus
[torus:~] peter>

Now you should be able to combine ssh certificates and yubikeys/smart cards

Use a smart card or HSM to securely store your SSH CA keys

Depending on the use case, SSH CA keys can be extremely sensitive. Possession of the private key gives you the ability to sign new certificate for arbitrary usernames that will grant access to all machines where this CA is trusted. This is why you should keep your CA keys very safe, preferably offline and of course encrypted (password protected).

One big problem with digital encryption keys is that it is extremely difficult to find out if you lost control over they keys. If they where copied you have no way of finding out. This is where hardware tokens comes in. If you can be sure that the key will never leave the hardware token, you have a better chance of knowing when they keys are lost or stolen.

OpenSSH have support for storing keys onto hardware tokens that talk PKCS#11 such as smart cards and hardware security modules.

If you want to store your personal SSH key on a smart card you can read more about that here: Using Smart Card enabled yubikey for ssh authentication in FreeBSD

Since a SSH CA is just a regular SSH key they can also be stored on smart cards. But there is a few subtle differences in how you use it. First of all you need a token with a RSA key present. There is no option in OpenSSH to ask for a specific key stored on the token, instead we specifiy the public key that matches the private key we want to use. Lets download the public key from the token:

$ ssh-keygen -D /usr/local/lib/opensc-pkcs11.so
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCOvhEqFq9Ualp1iYiNs0JFs3MgvGU+By/VvyW4qkymW+w/MmHAaHl+/UFnE+kgXChdYHaGEVxxGi6dQlSq+1ZKAWPJsOEbkysK6cgjgvP21gVNjL62TlQz+QfGF82mv0hfSGXQrZQR7VDs+6xJOe3S/0i1HvnnRTdR2v9QSJzd2EWNLmUcPy7+4x4rEB11G0oPt+Xyx60WaleJctwJHHhJS/jqHdvuf7HO6MS/EQn2NTnwIjChlmm2kUT7obnev/r6uEwz87NubnYJUrYImRDMafjS9taq8l7y33ydT00QHEI76kmrSSi7hTfmxUgStQWuQ2mq10YEVd8kZ2sqmC3N

We put this into a file, let say ssh_ca.pub. Now we are ready to start using the token for certificate signing.

$ ssh-keygen -s ssh_ca.pub -D /usr/local/lib/opensc-pkcs11.so -I key_id wack.pub 
Enter PIN for 'Framkant HSM Test (UserPIN)': 
Signed user key wack-cert.pub: id "key_id" serial 0 valid forever

To look at the certificate we can use ssh-keygen.

% ssh-keygen -L -f wack-cert.pub 
wack-cert.pub:
        Type: ssh-rsa-cert-v01@openssh.com user certificate
        Public key: RSA-CERT SHA256:AtPyAu1DL5cFruTo9XnsVz7tdec7xF9SbpX8DzsQrbs
        Signing CA: RSA SHA256:Pbdx6TAvXvwZTKQVMRYWsWYPomw6AxBVoqbtXgy9pfs
        Key ID: "key_id"
        Serial: 0
        Valid: forever
        Principals: (none)
        Critical Options: (none)
        Extensions: 
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

In a real life scenario I would recommend against this kind of certificate. Give it some validity and specify principals.

Two nice affordable options for hardware tokens are the Yubikey and the Smart Card HSM

OpenSSH with ECDSA keys on yubikey/smart card

In one of the latest versions of OpenSSH it is now possible to store ECDSA keys on smart cards. If you managed to use ssh with your RSA keys on the yubikey its fairly simple to go to ECDSA. The only thing you need is a late snapshot of OpenSSH portable and a patch.

# fetch http://www.mindrot.org/openssh_snap/openssh-SNAP-20151124.tar.gz
# tar zxf openssh-SNAP-20151124.tar.gz
# cd openssh 
# fetch "https://bugzilla.mindrot.org/attachment.cgi?id=2728" -o ecdsa.patch
# patch -s < ecdsa.patch
# ./configure
[...]
# gmake
[...]

Now you should be able to use get public keys from the smart card on your yubikey. Make sure pcscd is running then fetch the key with your newly compiled ssh-keygen.

# ./ssh-keygen -D /usr/local/lib/opensc-pkcs11.so
C_GetAttributeValue failed: 18
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAJGTLvC9BHSNPAfOw3s4lEix3zKLBKRgZlQ9kSxyttSG8XZ/NIoxm+ZYGbkYxji1kN7brMff21mgXGUzfxp58M=

References:
https://bugzilla.mindrot.org/show_bug.cgi?id=2474
http://lists.mindrot.org/pipermail/openssh-bugs/2015-September/015514.html
https://framkant.org/2015/11/using-smart-card-enabled-yubikey-for-ssh-authentication-in-freebsd/

Using Smart Card enabled yubikey for ssh authentication

This guide will try to show you how to use yubikey for ssh authentication

I recently found out that the yubikey neo had a built in smart card. Also, a few days ago Yubico released their fourth version of the yubikey introducing built in smart card as a standard feature. Me, having very little knowledge and experience with smart cards bought one just to play around with and I quickly found out that the card could be used to securely store encryption keys and certificates.

I use SSH alot both at home and at work, so this was the natural place to start. There is a short guide on how to use the yubikey with ssh on the yubikey developer site but this only covers the yubikey-part. This article will show you how to get things working in FreeBSD. But it will also skip the steps needed to configure the yubikey to have the smart card enabled, and how to generate keys and so on (yubikey software needed)

First if all you need to install a few packages.

# pkg install pcsc-lite
# pkg install opensc
# pkg install libccid

Then there i alot of stuff you can fiddle with using the pkcs11-tool, pkcs15-tool commands. But to get going you can just start the pcscd daemon manually and insert the yubikey into your computer.

# pcscd -f -d

If you have correctly generated a key (and certificate) on the yubikey in one of the slots you should now be able to run

$ ssh-keygen -D /usr/local/lib/opensc-pkcs11.so
C_GetAttributeValue failed: 18
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCOvhEqFq9Ualp1iYiNs0JFs3MgvGU+By/VvyW4qkymW+w/MmHAaHl+/UFnE+kgXChdYHaGEVxxGi6dQlSq+1ZKAWPJsOEbkysK6cgjgvP21gVNjL62TlQz+QfGF82mv0hfSGXQrZQR7VDs+6xJOe3S/0i1HvnnRTdR2v9QSJzd2EWNLmUcPy7+4x4rEB11G0oPt+Xyx60WaleJctwJHHhJS/jqHdvuf7HO6MS/EQn2NTnwIjChlmm2kUT7obnev/r6uEwz87NubnYJUrYImRDMafjS9taq8l7y33ydT00QHEI76kmrSSi7hTfmxUgStQWuQ2mq10YEVd8kZ2sqmC3N

To show the public part of your keys residing on the smart card. If this command was successful you can also add the keys to your ssh-agent using

$ ssh-add -s /usr/local/lib/opensc-pkcs11.so
Enter passphrase for PKCS#11: 
Card added: /usr/local/lib/opensc-pkcs11.so

and then you can list the keys with

$ssh-add -l
2048 8c:c9:99:1f:1b:98:42:af:9b:9b:93:e6:5b:ff:2a:94 /usr/local/lib/opensc-pkcs11.so (RSA)

To remove the card from the agent use

$ ssh-add -e /usr/local/lib/opensc-pkcs11.so
Card removed: /usr/local/lib/opensc-pkcs11.so

To connect somewhere using the keys on the smart card without the agent you can just use

$ ssh -I /usr/local/lib/opensc-pkcs11.so user@host.tld

There will probably be more guides in the future on how to use this further.

Update:

You can now use ECDSA keys stored on yubikey with OpenSSH.