Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Using a Yubikey for SSH CA Key Storage and Certificate Signing

Generate Passphrase for SSH CA Keys

Use diceware to generate a strong passphrase for your SSH CA keys:

$ sudo apt install diceware
$ diceware -d ' '

Create SSH CA Keys and Setup Yubikey

First, clone this repo to the server system:

$ git clone https://github.com/openavr/sshca-yk.git
$ cd sshca-yk

To generate the User and Host SSH CA keys and load them into a Yubikey:

Usage: ./ca-create.sh <org> <common-name>

For example, for the example.com domain, with a common name of TestExample (this will prompt you to enter the passphrase for the keys):

$ ./ca-create.sh example.com TestExample

The generated private keys are now on-disk and in the Yubikey. The on-disk copies must be protected and not shared.

Verify the contents of the Yubikey:

$ ykman piv info
...
Slot 84 (RETIRED3):
  Private key type: ED25519
  Public key type:  ED25519
  Subject DN:       CN=TestExample User SSH CA,O=example.com
  Issuer DN:        CN=TestExample User SSH CA,O=example.com
  Serial:           52:1e:44:b0:ca:80:5c:11:75:6e:48:c7:1a:d8:a4:ce:83:d8:5c:1c
  Fingerprint:      77348c2ff32ecc7b5ea8820a0a22509bb1a97c02c67ea8f02af582bd06ac12bc
  Not before:       2026-07-26T19:21:16+00:00
  Not after:        2026-10-24T19:21:16+00:00
...

Generate an authorized_keys_ca file that has entries you can copy to your ~/.ssh/authorized_keys file on the server that you want to allow users to log into using certificates:

$ ./generate-auth-keys.sh example.org

The generated authorized_keys_ca can be copied to any server as it does not contain any sensitive material.

Server Side User SSH CA Setup

Copy the User SSH CA line from the generated authorized_keys_ca file into your ~/.authorized_keys file on the server(s).

Alternatively, you could install the User SSH CA public key globally so that it can be used for all user accounts by adding it to the TrustedUserCAKeys entry in the /etc/ssh/sshd_config file. See the sshd_config(5) man page for more details.

$ sudo cp keys-ca/example.com/id_ed25519_user_ca.pub /etc/ssh
$ echo "TrustedUserCAKeys /etc/ssh/id_ed25519_user_ca.pub" \
    | sudo tee /etc/ssh/sshd_config.d/user_ca.conf
$ sudo systemctl restart sshd

The target user account name on the server should be at least one of the principals in the certificate file.

The server side user account is now setup to accept logins from clients using certificates signed by the SSH User CA.

Client Side User SSH CA Setup

Clone this repo to the client system:

$ git clone https://github.com/openavr/sshca-yk.git
$ cd sshca-yk

Plug the Yubikey into the client system.

Extract the CA public key from the Yubikey:

$ ykman piv info
$ ssh-keygen -D /usr/lib/x86_64-linux-gnu/libykcs11.so \
    | grep 'Retired Key 3' > keys-ca/example.com/id_ed25519_user_ca.pub

Generate and sign a user ssh key pair and certificate:

$ ./ca-sign-user.sh example.com ${USER}

You should now be able to login to the server as ${USER}:

$ ssh -i ./keys-user/id_ed25519_${USER} <server>

You can also create the key and sign the cert in your ~/.ssh directory:

$ ./ca-sign-user.sh example.com ${USER} ~/.ssh/id_ed25519_${USER}

Generating an ed25519 and loading it into a Yubikey

Background and OS Setup

The format of the private generated by openssh can not be imported directly into a Yubikey, it must be converted first.

You must use openssh >= 10.3p1 in order to be able to generate ed25519 keys and convert them to PEM or PKCS8 format that can be loaded into Yubikey.

For Debian-13 (Trixie), you need to install the openssh tools using debian backports. Setup debian backports with the instructions here:

Once backports is setup, install the newer version of openssh:

$ sudo apt update
$ sudo apt install \
    openssh-client/trixie-backports \
    openssh-server/trixie-backports \
    openssh-sftp-server/trixie-backports

You only need openssh >= 10.3p1 if you are loading the CA or user keys into the Yubikey, and do not need the newer version if you are only using the Yubikey to sign user or host certificates.

NOTE: The -N '' will generate a key without a passphrase which is probably not what you want.

Generate a ed25519 key pair:

$ ssh-keygen -t ed25519 -N '' -f id_ed25519_foo

Convert the private key to a format that can be imported into a yubikey:

$ cp id_ed25519_foo id_ed25519_foo.key
$ ssh-keygen -p -m PKCS8 -N '' -f id_ed25519_foo_key.pem

Import the private key into a yubikey:

$ ykman piv keys import 85 id_ed25519_foo_key.pem
$ ykman piv info

Checking if Keys Match

To verify is a private key and a public match, use this:

# match if no differences and exit code of 0
$ diff <(ssh-keygen -l -v -f $sshkeyfile) <(ssh-keygen -l -v -f $sshpubfile)

To see if a public key matches the private key stored in a Yubikey slot, you first need to dump all of the public keys stored in the yubikey. This can be done with the following command:

$ ssh-keygen -D /usr/lib/x86_64-linux-gnu/libykcs11.so

Then you can compare against another public key, but this is probably not needed since now you have the public keys of the private keys in the Yubikey and can just use them.

Required Dependencies

Run the following command to install basic tool dependencies needed for these scripts:

$ sudo apt install ykcs11 yubico-piv-tool yubikey-manager libyubikey-udev

About

Utility scripts for using Yubikeys to store SSH user and host Certificate Authority keys.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages