Featured image

How to Yubikey: a configuration cheatsheet

This post shows different use cases for a Yubikey. There are also command line examples in a cheatsheet like manner. I’m using a Yubikey 5C on Arch Linux. If you run into issues, try to use a newer version of ykman (part of yubikey-manager package on Arch).

kmille@linbox:~ ykman --version
YubiKey Manager (ykman) version: 4.0.9

Some features depend on the firmware version of the Yubikey. The tooling (like the wording) around the Yubikey is sometimes a bit confusing. I use this guide as a reference if I need to reconfigure something after a long time. It helped me in the past, so I made a clean rewrite. I hope it helps you too. Please get in contact with me if something is wrong/missing (Hacker News discussion).

Getting started

To check if your Yubikey was detected successfully and find out which modes are enabled, use:

kmille@linbox:~ ykman list
YubiKey 5 NFC (5.1.2) [OTP+FIDO+CCID] Serial: 1312

kmille@linbox:yubikey ykman info
Device type: YubiKey 5 NFC
Serial number: 1312
Firmware version: 5.1.2
Form factor: Keychain (USB-A)
Enabled USB interfaces: OTP, FIDO, CCID
NFC transport is enabled.

Applications    USB             NFC
FIDO2           Enabled         Enabled
OTP             Enabled         Enabled
FIDO U2F        Enabled         Enabled
OATH            Enabled         Enabled
YubiHSM Auth    Not available   Not available
OpenPGP         Enabled         Enabled
PIV             Enabled         Enabled

ykman config nfc --disable PIV
ykman config usb --enable-all

Time based one time passwords as second factor

In general, TOTP (time based one time password) is used for 2FA (two-factor authentication). It gives you a 6 (sometimes 8) digit token you have to enter during login. The secret key is formatted in base32 (e. g. H7TTOPOIDLOXGT4E). You can add 32 of these secrets to a Yubikey device (at least for the Yubikey 5 NFC). If you prefer a GUI application, you can use Yubico Authenticator (part of the yubioath-desktop package). Yubico Authenticator does not store the secret, it asks the Yubikey device for the token. There is also the Yubico Authenticator with NFC support for Android.

Command line tooling with ykman:

kmille@linbox:~ ykman oath accounts add test --touch
Enter a secret key (base32): H7TTOPOIDLOXGT4E
kmille@linbox:~ ykman oath accounts list
test

kmille@linbox:~ ykman oath accounts code
Touch your YubiKey...
test  629211

kmille@linbox:~ ykman oath accounts code -s test
Touch your YubiKey...
940658

kmille@linbox:~ ykman oath accounts delete test
Delete account: test ? [y/N]: y
Deleted test.

kmille@linbox:~ ykman oath accounts list
kmille@linbox:~

It’s important to backup the secret. If your Yubikey is lost, you can still login by using the secret with other tools like the Google Authenticator or by using a few lines of python code. KeepassXC also has a neat feature for TOTP. But please don’t save it in the same Keepass database you use daily.

import time
import pyotp

otp = pyotp.totp.TOTP("H7TTOPOIDLOXGT4E")
while 1:
    print(otp.now())
    time.sleep(2)

This prints the 6-digit token every two seconds (needs pip install --user pyotp).

Secure and convient: U2F (Universal 2nd Factor)

Sometimes U2F is also called FIDO2 or WebAuthn. Like TOTP tokens, U2F can be used during web logins for two-factor authentication. The TOTP variant is prone to phishing attacks, as users enter their tokens also on phishing sites. U2F solves this problem by using a challenge response mechanism that includes the SSL Channel ID and the browser url of the login page (docs). If you use U2F, the browser speaks directly to the Yubikey device, no special drivers or tools are necessary. All major browsers support U2F. On Arch Linux, you have to install the libfido2 package. If you use Firejail sandbox, you need to set browser-disable-u2f no in /etc/firejail/firejail.config.

U2F is very easy to use. During setup, you pair an online account with a Yubikey device. During login, you only have to touch the Yubikey. Watch this demo on Youtube to get a feeling for it. You can test U2F on the Yubico demo website. It’s also very nice to use it on Android with NFC.

How does it work? For U2F, the Yubikey holds an asymmetric keypair (private and public key). If you add the Yubikey as a security device, the online service just needs to save the public key. During authentication, the possession of the private key must be proven (for example by signing a text with the private key).

Backup strategy: You can’t make a backup because you don’t have access to the secret/private key. So you have to add multiple U2F devices to your account or add TOTP as additional 2FA method. A backup can also be your IT department, if they can give you access again. Google deployed U2F to their 50,000 employees.

SSH with FIDO2 (U2F)

I don’t use this feature, because my Yubikey firmware is too old for my needs. I can’t use ed25519 (only the NSA curve sk-ecdsa-sha2-nistp256) and the resident feature works only on firmware 5.2.3 or higher. If you are interested, here are good reads:

kmille@linbox:~ ssh-keygen -t ed25519-sk
Generating public/private ed25519-sk key pair.
You may need to touch your authenticator to authorize key generation.
Key enrollment failed: requested feature not supported

kmille@linbox:~ ssh-keygen -t ecdsa-sk -O resident
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
Key enrollment failed: requested feature not supported

kmille@linbox:~ ssh-keygen -t ecdsa-sk
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter file in which to save the key (/home/kmille/.ssh/id_ecdsa_sk):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/kmille/.ssh/id_ecdsa_sk
Your public key has been saved in /home/kmille/.ssh/id_ecdsa_sk.pub

Static password on touch

You can use the Yubikey to simulate a keyboard (HID - Human Interface Device) to enter a static password. For the YubiKey 5 NFC, there are two slots you can use (a short touch triggers slot 1, long touch triggers slot 2). I don’t see any use case or security benefits by using the static password feature. Even if you enter a password manually and concatenate it with the password of the Yubikey, a keylogger still gets both parts (assumption: You don’t reuse passwords). The only advantage would be that you don’t have to remember the complex password. This is how you can use it:

kmille@linbox:~ ykman otp static --keyboard-layout de 1
Enter a static password: hello world
Slot 1 is already configured. Overwrite configuration? [y/N]: y

# touch the Yubikey
kmille@linbox:~ hello world
zsh: command not found: hello

kmille@linbox:~ ykman otp delete 1
Do you really want to delete the configuration of slot 1? [y/N]: y
Deleting the configuration in slot 1...

kmille@linbox:~ ykman otp info
Slot 1: empty
Slot 2: programmed

kmille@linbox:~ ykman otp static --generate 2 --length 32
Slot 2 is already configured. Overwrite configuration? [y/N]: y

# touch the Yubikey
kmille@linbox:~ FiNIFRNhbDRhKEbFLrDNLbkJedkiELhn
zsh: command not found: FiNIFRNhbDRhKEbFLrDNLbkJedkiELhn
kmille@linbox:~

kmille@linbox:~ ykman otp swap
Swap the two slots of the YubiKey? [y/N]: y
Swapping slots...

If you prefer a GUI tool, you can use the YubiKey Personalization Tool. Steps are

  1. Go to ‘static password mode’
  2. Scan code
  3. Choose configuration slot 1/2 (short/long press)
  4. You have to choose a keyboard layout before you can enter a password (usability is meh)
  5. Enter password
  6. Write configuration
  7. Test it an a text editor

Securing a Keepass database

To be precise, the Yubikey is not a true second factor. KeepassXC uses the challenge-response mechanism of the Yubikey. The challenge (and therefore the response) is not unique for every authentication attempt (decrypting the database). So the challenge/response can be sniffed via USB by an attacker. For more information read this answer on StackExchange and also check the FAQs of KeepassXC about the use of Yubikey. For the setup, you first have to enable the challenge-response feature and add/generate a secret for a slot:

kmille@linbox:~ ykman otp info
Slot 1: empty
Slot 2: empty

kmille@linbox:~ ykman otp chalresp --touch --generate 2
Using a randomly generated key (hex): 874352e9f826d9c0cbc497113cbf7921fb962d76
Program a challenge-response credential in slot 2? [y/N]: y

kmille@linbox:~ ykman otp info
Slot 1: empty
Slot 2: programmed

To pair your Keepass database with the Yubikey, open your database (I use KeePassXC) and go to: Database -> Database Security -> Change Password -> add additional protection -> Add Challenge-Response -> Refresh

This also works nice with NFC on Android using the Keepass2Android app (needs ykdroid, choose “Password + Challenge-Response for KeepassXC”). If you want to have a backup for your Yubikey, use another device with the same secret.

kmille@linbox:~ ykman otp chalresp --touch 2
Enter a secret key: 874352e9f826d9c0cbc497113cbf7921fb962d76
Program a challenge-response credential in slot 2? [y/N]: y

Keep in mind that this feature uses the same slots as the static password functionality. If your Keepass is sandboxed with firejail, you need the following lines in ~/.config/firejail/keepassxc.local:

protocol netlink,unix
ignore private-dev

A second factor for full disk encryption

You can use the challenge-response feature of the Yubikey to enable 2FA for full disk encryption (luks). There is a project for Debian and one for Arch Linux. Both work basically the same. What happens under the hood is:

  1. initialization: add a secret to the Yubikey (HMAC-SHA1 Challenge-Response)
  2. factor one is the challenge you need to enter manually during boot (it gets sha256sumed before sending it to the Yubikey)
  3. the second factor is the response calculated by the Yubikey (code)
  4. challenge and response are concatenated (code) and added as a password to a luks key slot (code)

You can also write the challenge to a config file. Then you can decrypt the disk during boot only with the Yubikey, you don’t have to enter a password (challenge). There are tools which make the usage pretty simple (ykfde-format, ykfde-enroll, ykfde-open). This is how you can use it:

kmille@linbox:~ ykman otp chalresp 2
Enter a secret key: supersecret2
Program a challenge-response credential in slot 2? [y/N]: y
kmille@linbox:~

# create a test disk
kmille@linbox:~ truncate -s 20M disk
# Hint: I set YKFDE_CHALLENGE_PASSWORD_NEEDED="1" and DBG="1" in /etc/ykfde.conf
kmille@linbox:~ ykfde-format disk
 > ~ slot status 'ykinfo -q -2': 1
WARNING: This script will run 'cryptsetup luksFormat disk'.  If this is not what you intended, please abort.
 > Please provide the challenge.
   Enter challenge: 123
 > Please repeat the challenge.
   Enter challenge: 123
   Running: 'ykchalresp -2 a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3'...
   Remember to touch the device if necessary.
   Received response: '0c66dacbf9155c6f48b774ca7c2520735b3dce7c'
 > Passing 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae30c66dacbf9155c6f48b774ca7c2520735b3dce7c' to 'cryptsetup'
   New LUKS device successfully formatted
# Let's reprodcue it manually:
# Step 1: sha256 of the challenge "123"
kmille@linbox:~ echo -n 123 | sha256sum
a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3  -

# Step 2: Use the challenge-response feature (slot 2). Input: sha256("123")
kmille@linbox:~ ykchalresp -2 a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
0c66dacbf9155c6f48b774ca7c2520735b3dce7c

# Step 3: concat challenge|response and use it as password to decrypt the luks device
kmille@linbox:~ echo "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae30c66dacbf9155c6f48b774ca7c2520735b3dce7c" | sudo cryptsetup open disk test-disk
[sudo] password for kmille:
kmille@linbox:~ sudo cryptsetup close test-disk
kmille@linbox:~ rm disk

As a backup, you only need to store the challenge-response secret of the Yubikey at a save place. If you don’t have a backup device, you can use this small challenge-response implementation in python (it’s just SHA-1 HMAC following RFC2104):

kmille@linbox:~ ykman otp chalresp --touch --generate 2
Using a randomly generated key (hex): 00b96ec0a15fe9c6d752d2d89793b434ef7c49c5
Program a challenge-response credential in slot 2? [y/N]: y

kmille@linbox:~ echo -n test | ykchalresp -2 -i-
bcfb0464611a4b29444d0288c9e4ba91db13ed72

kmille@linbox:~ cat test.py
from hashlib import sha1
from binascii import unhexlify
import hmac

key = unhexlify("00b96ec0a15fe9c6d752d2d89793b434ef7c49c5")
message = b"test"

hashed = hmac.new(key, message, sha1)
mac = hashed.hexdigest()
print(mac)

kmille@linbox:~ python test.py
bcfb0464611a4b29444d0288c9e4ba91db13ed72
kmille@linbox:~ 

PIV (Personal Identity Verification) aka smartcard

I use the PIV functionality for SSH public key authentication. Unfortunately, only one keypair can be stored on the Yubikey 5C for ssh authentication (using the PIV method). Also, the maximum RSA key size is limited to 2048. To get PIV working, a service called pcscd (PC/SC Smart Card Daemon) needs to be running. On Arch Linux, install the opensc package, for a Debian based OS install pcscd. Then, start/enable the service:

systemctl enable --now pcscd.service
systemctl status pcscd.service

PINs for PIV: the why and how

A PIV-enabled YubiKey has a PIN, a PUK and a Management Key. The PIN is used during normal operation to authorize an action such as creating a digital signature for any of the loaded certificates. The PUK can be used to reset the PIN if it is ever lost or becomes blocked after the maximum number of incorrect attempts. If an incorrect PIN is given 3 times consecutively, the PIN will become disabled. If you’ve set a PUK, then you can use that PUK to reset the PIN to a new value, and it will become enabled and usable again. If an incorrect PUK is given 3 times consecutively, it will become blocked as well. When both the PIN and the PUK are blocked, the device can be reset. This returns the PIV functionality of the YubiKey to a factory setting, setting the default PIN, PUK and Management Key values, as well as removing any stored keys and certificates. Once reset, the device is ready to be re-initialized.

All PIV management operation of the YubiKey require a 24 byte 3DES key, known as the Management Key. You can either explicitly set a 24 byte key (the YubiKey PIV Manager can generate one for you), or you can choose to not set a Management Key, instead using the PIN for these operations. If so, you will be asked to provide your PIN instead of your Management Key whenever you perform a management operation, such as importing a new certificate, or generating a new key pair. Please check the considerations on the website when using a PIN for PIV management.

The previous text was copied from the Yubico website. The most important thing: You can reset the PIV configuration if something goes wrong:

kmille@linbox:~ ykman piv reset
WARNING! This will delete all stored PIV data and restore factory settings. Proceed? [y/N]: y
Resetting PIV data...
Success! All PIV data have been cleared from the YubiKey.
Your YubiKey now has the default PIN, PUK and Management Key:
        PIN:    123456
        PUK:    12345678
        Management Key: 010203040506070801020304050607080102030405060708

To change the management key, use:

kmille@linbox:~ cat gen-mgmt-key.py
import os
from binascii import hexlify
print(hexlify(os.urandom(24)).decode())

kmille@linbox:~ python gen-mgmt-key.py
faf6bf013ed8fc473e0b47e5502d0c75fda8e40ece5bce24

kmille@linbox:~ ykman piv access change-management-key
Enter PIN: 
Enter the new management key: 
Repeat for confirmation: 

To change PIN/PUK or unblock the device, use:

kmille@linbox:~ ykman piv access change-pin
Enter the current PIN: 
Enter the new PIN: 
Repeat for confirmation: 
New PIN set.

kmille@linbox:~ ykman piv access change-puk
Enter the current PUK: 
Enter the new PUK: 
Repeat for confirmation: 
New PUK set.

kmille@linbox:~ ykman piv info                                            
PIV version: 5.1.2
PIN tries remaining: 0
...

kmille@linbox:~ ykman piv access unblock-pin
Enter PUK: 
Enter a new PIN: 
PIN unblocked

kmille@linbox:~ ykman piv access set-retries 5 5
Enter a management key [blank to use default key]: 
Enter PIN: 
WARNING: This will reset the PIN and PUK to the factory defaults!
Set the number of PIN and PUK retry attempts to: 5 5? [y/N]: y
Default PINs are set:
        PIN:    123456
        PUK:    12345678

SSH with PIV: generate private key on Yubikey

In the following, you can see how to generate a private key on the Yubikey. The private key will never leave the Yubikey, so you can’t export/backup it. I don’t recommend using ECDSA (P-256 or P-384) and use 2048 bit RSA, which is the default.

# Hint: 9a is the key slot, pubkey.pem the file where the public key will be stored
kmille@linbox:~ ykman piv keys generate 9a pubkey.pem
Enter a management key [blank to use default key]:
# Hint: the generate command supports some useful parameters
#  --algorithm RSA1024|RSA2048|ECCP256|ECCP384   Algorithm to use in key generation
#  --pin-policy [DEFAULT|NEVER|ONCE|ALWAYS]      PIN policy for slot.
#  --touch-policy [DEFAULT|NEVER|ALWAYS|CACHED]  Touch policy for slot.

kmille@linbox:~ ykman piv certificates generate --subject "CN=yubico" 9a pubkey.pem
Enter a management key [blank to use default key]:
Enter PIN:
kmille@linbox:~

kmille@linbox:~ ykman piv info
PIV version: 5.1.2
PIN tries remaining: 3
Management key algorithm: TDES
CHUID:  3019d4e739da739ced39ce739d836858210842108421c84210c3eb3410aeab759a2258a6311edece0f51cb8fb1350832303330303130313e00fe00
CCC:    No data available.
Slot 9a:
        Algorithm:      RSA2048
        Subject DN:     CN=yubico
        Issuer DN:      CN=yubico
        Serial:         271029653146178331059499985773756430831562756416
        Fingerprint:    dd721071c21e2c5b2a4b2d34025ab8ce57124fd66368c2e01656c653971db350
        Not before:     2023-02-07 13:32:41
        Not after:      2024-02-07 13:32:41

# Hint: show public key
kmille@linbox:~ ssh-keygen -D /usr/lib64/pkcs11/opensc-pkcs11.so -e
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+uLBEfTF6XRTetzZ7MtxlK4yrPZnp13PGmTeSW5qwO36ycORDylR8P3bfaK/v4kuSYSzaumgGZTQ7tUO14r8vZhCzimX0oCSjy3RhaKEb0Dpk2yFxQyeqCdTOygBle8QzvVqBhOFNtjTUtzl8Tmr8AVEl/zMWk/N76ilhbp5fm4ywAwIOY66m5nttEG3ykTc98DzS/+aY5YgpsiADADAE38E7rlMHHVAQQ8cwUIyIHPplQZlbdjOH2FFroxhf8vUDjDLWnHAU2Chr7tV+f9p/IN812pOcejCtBlCyAS72JjuC0K9QEIXvfuQqkFJ7tUdvRcR38wcA0w1tWhsWoko9 PIV AUTH pubkey

kmille@linbox:~ ssh-keygen -D /usr/lib64/pkcs11/opensc-pkcs11.so -e >> ~/.ssh/authorized_keys

kmille@linbox:~ ssh -I /usr/lib64/pkcs11/opensc-pkcs11.so localhost
Enter PIN for 'yubico':
Last login: Tue Feb  7 13:31:13 2023 from ::1
kmille@linbox:~

kmille@linbox:~ rm pubkey.pem
kmille@linbox:~

kmille@linbox:~ ykman piv certificates delete 9a
Enter a management key [blank to use default key]:

Using it with ssh-agent

kmille@linbox:~ ssh-add -s /usr/lib64/pkcs11/opensc-pkcs11.so
Enter passphrase for PKCS#11:
Card added: /usr/lib64/pkcs11/opensc-pkcs11.so

kmille@linbox:~ ssh-add -l
2048 SHA256:WhnjNX3z7qfJdr4aNFlK//StX6hOXx7oA33yCVbjn7Q PIV AUTH pubkey (RSA)

kmille@linbox:~ ssh localhost
Last login: Tue Feb  7 14:33:19 2023 from ::1
kmille@linbox:~

You can also use PKCS11Provider /usr/lib64/pkcs11/opensc-pkcs11.so in ~/.ssh/config.

SSH with PIV: import existing private key to Yubikey

To import an existing ssh key to the Yubikey, the private key must be converted in a proper format. You also have to create a file with the public key. Exporting it from the Yubikey only works with firmware 5.3 or later (see this Github issue).

# Hint: -P means no password, ssh-keygen uses 3072 bit as default on Arch
# Yubikey supports only 2048 bit max
kmille@linbox:tmp ssh-keygen -f existing  -b 2048 -P ""
Generating public/private rsa key pair.
Your identification has been saved in existing
Your public key has been saved in existing.pub

# Hint: the private key must be converted first
kmille@linbox:tmp head -n 1 existing         
-----BEGIN OPENSSH PRIVATE KEY-----

kmille@linbox:tmp ssh-keygen -p -m pem -f existing
Key has comment 'kmille@linbox'
Enter new passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved with the new passphrase.

kmille@linbox:tmp head -n 1 existing
-----BEGIN RSA PRIVATE KEY-----

kmille@linbox:tmp ykman piv keys import 9a existing
Enter a management key [blank to use default key]:

kmille@linbox:tmp openssl rsa -in existing -pubout > testpub.pem
writing RSA key
kmille@linbox:tmp head -n 1 testpub.pem
-----BEGIN PUBLIC KEY-----

kmille@linbox:tmp ykman piv certificates generate --subject "CN=yubico" 9a testpub.pem
Enter a management key [blank to use default key]:
Enter PIN:
kmille@linbox:

kmille@linbox:tmp ykman piv info
PIV version: 5.1.2
PIN tries remaining: 3
Management key algorithm: TDES
CHUID:  3019d4e739da739ced39ce739d836858210842108421c84210c3eb34108897deb27c93ec8f6ebd0aa44d1139ef350832303330303130313e00fe00
CCC:    No data available.
Slot 9a:
        Algorithm:      RSA2048
        Subject DN:     CN=yubico
        Issuer DN:      CN=yubico
        Serial:         476405504585636348134209109957833992452830001643
        Fingerprint:    d723fce0a85c0105e4485d01fe264a6dd5e6677465410f1f90b0446f62b1bf8c
        Not before:     2023-02-26 19:25:46
        Not after:      2024-02-26 19:25:46

Modern file encryption with age

age is a simple, modern and secure file encryption tool, format, and Go library. There is also age-plugin-yubikey, a plugin for age clients like age and rage, which enables files to be encrypted to age identities (an age identity is like a pgp public key) stored on a YubiKey. To use it on Arch Linux, install the age-plugin-yubikey package. There is also a .deb package on the Github release page. age-plugin-yubikey currently only supports the ECCP256 curve (source, source).

In terms of backup: The private key is stored on the Yubikey and can not be extracted. To protect yourself from a broken/stolen/lost Yubikey, use a second Yubikey device and encrypt everything a second time with the identity of the backup Yubikey (see also this Github issue). It’s not possible to import a key (issue).

Below are the commands to generate a new private key on the Yubikey and encrypt/decrypt data with the identity. I think slot 82 to 94 can be used to store identities (source). You can just run age-plugin-yubikey to get an interactive setup for a new identity. The tool also supports --touch-policy (always, cached, never) and --pin-policy (always, once, never).

kmille@linbox:~ age-plugin-yubikey --generate --name test123
Enter PIN for YubiKey with serial 1312 (default is 123456): [hidden]
👆 Please touch the YubiKey
#       Serial: 1312, Slot: 1
#         Name: test123
#      Created: Sun, 05 Feb 2023 18:17:32 +0000
#   PIN policy: Once   (A PIN is required once per session, if set)
# Touch policy: Always (A physical touch is required for every decryption)
#    Recipient: age1yubikey1q228ff7yqw9pfducrzseqfsk8epg9lgluwetkdd0u48c0v9vg4t6gqkak3r
AGE-PLUGIN-YUBIKEY-1YELEWQYZ6DNC07QXHA5AW

# Hint: --list shows metadata and public key of all slots stored on Yubikey
kmille@linbox:~ age-plugin-yubikey -l
#       Serial: 1312, Slot: 1
#         Name: test123
#      Created: Sun, 05 Feb 2023 18:17:32 +0000
#   PIN policy: Once   (A PIN is required once per session, if set)
# Touch policy: Always (A physical touch is required for every decryption)
age1yubikey1q228ff7yqw9pfducrzseqfsk8epg9lgluwetkdd0u48c0v9vg4t6gqkak3r

# Hint: --identity returns a string on stdout which you can use for
# 'age -d -i <here>'. It  tells age which private key to use for decryption
kmille@linbox:~ age-plugin-yubikey -i --slot 1 > identity-1.txt
Recipient: age1yubikey1q228ff7yqw9pfducrzseqfsk8epg9lgluwetkdd0u48c0v9vg4t6gqkak3r

kmille@linbox:~ cat identity-1.txt
#       Serial: 1312, Slot: 1
#         Name: test123
#      Created: Sun, 05 Feb 2023 18:17:32 +0000
#   PIN policy: Once   (A PIN is required once per session, if set)
# Touch policy: Always (A physical touch is required for every decryption)
#    Recipient: age1yubikey1q228ff7yqw9pfducrzseqfsk8epg9lgluwetkdd0u48c0v9vg4t6gqkak3r
AGE-PLUGIN-YUBIKEY-1YELEWQYZ6DNC07QXHA5AW

# Hint: encrypt tmp/test.txt with an identity/public key and write it to tmp/test.txt.age
kmille@linbox:~ cat tmp/test.txt | age -r age1yubikey1q228ff7yqw9pfducrzseqfsk8epg9lgluwetkdd0u48c0v9vg4t6gqkak3r > tmp/test.txt.age

# Hint: decrypt it with the Yubikey (I have to touch it)
kmille@linbox:~ cat tmp/test.txt.age | age -d -i identity-1.txt > tmp/test.txt
kmille@linbox:~

kmille@linbox:~ ykman piv info
PIV version: 5.1.2
PIN tries remaining: 3
Management key algorithm: TDES
Management key is stored on the YubiKey, protected by PIN.
CHUID:  3019d4e739da739ced39ce739d836858210842108421c84210c3eb3410c0a9799579cbe476887b1f7ea5a74a6c350832303330303130313e00fe00
CCC:    No data available.
Slot 82:
        Algorithm:      ECCP256
        Subject DN:     CN=test123,OU=0.3.2,O=age-plugin-yubikey
        Issuer DN:      CN=test123,OU=0.3.2,O=age-plugin-yubikey
        Serial:         875428878573667959096445206907039728936329227404
        Fingerprint:    82ac5b1bc7f640ad58e29096b68c39507f80c335dd69a95971a6fe7f4a2c33c7
        Not before:     2023-02-05 18:17:32
        Not after:      9999-12-31 23:59:59
...

kmille@linbox:~ ykman piv certificates delete 82
Enter PIN:
kmille@linbox:~ age-plugin-yubikey -l
kmille@linbox:~

Future work

OpenPGP with Yubikey

OpenVPN with Yubikey

Ressources