Looking at YubiKey 5

All those authenticators

I don’t normally write about specific products, but I was asked to take a look at the YubiKey series (primarily 4 and 5) and write up a summary of when and how it can be used.

This is timely, because CISA is pushing for access management enhancements and recently published a chart for phishing resistance.

I thought this interesting; typically I’ve looked at this from a user perspective (“can I use this to secure access to my bank account?”). But this time I needed to look at it from an Enterprise perspective (“Is it safe to allow our employees to use this to access our systems?”).

There’s a different set of challenges and requirements. As a user I could take a risk (“Eh, I can store the password in an encrypted text file and trust no one can access my machine”), but from an enterprise perspective we can’t necessarily trust the employee to make the right decision; they’re not security professionals and may expose the company to risk.

Lots of authenticators

YubiKey supports a number of authenticators, and they have different characteristics. Some of them are suitable for passwordless, others may only be suitable for MFA and others… probably shouldn’t be used, at least for workforce authentication, but may be good for customers (eg Harry logging into his bank account). I’m going to summarize as best I can. This has got a little long, but there is a table at the end!

Note that the YubiKey supports all of these at the same time. So we need to make sure we know what mode is being used at any time.

I might have got some things wrong. Let me know in the comments if you spot something!

U2F

U2F (Universal Second Factor) is a strong phishing resistant token.

When registering a device with a URL the YubiKey generates a key pair using the target protocol, hostname, part as part of the seed value (along with embedded encryption key that’s unique the YubiKey) to generate the keys. This means that abc.example.com will get a different keypair to abc.example.org. The public key (and “handle”) is sent to the remote server and that’s what is stored as your authentication token. This handle may include the private key encrypted with the encryption key embedded into the YubiKey.

When you then try to login to a site the protocol/hostname/port and handle are sent to the key. The YubiKey will verify the handle matches the protocol/hostname/port and was issued by this key. It will then use the decrypted private key to complete a standard public key authentication process. If a different key was used then the embedded information is different so the generated key would change, so the server can be sure the person has possession of the same key that was used for registration. Similarly if a different URL was used then the protocol/hostname/port would be different and so the handle wouldn’t validate; a MITM on a phishing URL wouldn’t be able to intercept the response and use that to login to a real site. MITM is possible at registration time, of course, so a user could think they were using secure MFA when they’re really not.

U2F may be implemented by software and so not be strong (encryption keys could be copied to multiple places, for example). There is an attestation process available, where the public key sent from the YubiKey is signed with the vendor attestation key. This means that it’s possible to verify that the U2F key is “strong”. Without this attestation we can not be sure the device presented is a hardware token or a piece of software with copied keys. With attestation it may be suitable as a 2nd factor, but without we can’t assume it’s strong. We may allow it for customer authentication without attestation; “If Harry wants to use a weak MFA device then it’s his lookout!”

FIDO2

FIDO2 is very similar to U2F. It’s an evolution of it, and the specs are backwardly compatible. However FIDO2 introduces some new functions. In particular it allows for forcing the user to prove they are the authorized holder of the device; typically this is a PIN or biometric.

By default YubiKeys do not protect FIDO tokens, but when the UV (User Verification) flag is set then the user will be asked to set a PIN or biometric. With YubiKey 4 the PIN is minimum 4 characters, with YubiKey 5 the PIN is minimum 6 characters. Note the PIN need not be just digits; any normal alphanumeric can be used. After 3 failed PIN attempts the device needs to be removed and reinserted. After 8 failed PIN attempts the token is locked. Unlocking requires a “master reset” and removes the private key, so effectively invalidates the token.

As with U2F there is an attestation process. With attestation and UV then this becomes a viable passwordless solution. With attestation but no UV then it may only be used as a 2nd factor. Without attestation at all then we may only use it for customer authentication, same as U2F.

Since the attestation and UV requirements are set by the server (on registration and login) it’s possible for different services to have different stances. This could get confusing. We can not simply say “FIDO2 is good for passwordless”; we must say “FIDO2 with device attestation and restriction to YubiKey and with User Verification is good”.

Microsoft Azure AD can perform FIDO2 authentication and appears to have the necessary configuration options

Windows desktops can be configured to support FIDO2 authentication, but the machines must be Azure AD (or hybrid) joined. Simple domain-joined machines can not do this. There are other limitations.

Apple have committed to supporting FIDO.

Non-web based applications can use FIDO2 via “out of band” mechanisms; e.g. the user may get sent a link (SMS, Email, copy’n’paste…) that they enter into a browser and complete authentication there. This obviously requires application changes.

Both Android and iOS devices also provide native FIDO2 authentication mechanisms. In testing on my Android device with the UV flag set I was prompted to fingerprint.

PIV (Smart Card)

In PIV mode, the YubiKey acts as a smart card. A public/private key is stored on the key as certificates. The certificate is signed by a CA trusted by the service. Essentially this follows a similar process to client-side authentication in mTLS; the server can validate the public key matches requirements (signed by a CA, contains the right metadata, etc) and then do standard public key cryptography to verify the private key is present.

YubiKeys automatically protect the certificates with a PIN (see FIDO2 about PINs); the PIN can not be removed (YubiKey bio devices don’t support PIV mode at present). The private key can not be extracted from the device. Because this is a certificate based process the keys can expire (and so need renewal) and a CRL (certificate revocation list) is available.

The key can be put onto the card in two different ways.

  1. The first is that an external program can generate the key pair, get it signed by the CA, then put them on the card. This is problematic because it means the private key will live (for at least a small time) outside of the secure device and so could be copied. We also don’t necessarily have a way to verify the device is a trusted YubiKey and not an emulator.

  2. The second is to have the YubiKey generate the key pair, and the CSR (certificate signing request). This generation process comes with an optional attestation process, which can be used to prove the keys were generated by a YubiKey and not a piece of software; the CA signing process can perform the validation and only sign the cert if it passes. The signed certificate can then be placed back on the device. In this way we can be sure that the private key was securely generated on the YubiKey and can not be copied.

We should require the YubiKey generation process be followed, and never store private keys outside of the secure device. When the key is used the user is prompted for their PIN/biometric. This gives us sufficient trust to let the YubiKey in PIV mode be used for passwordless access.

Windows supports PIV mode using the built in smart card services.

MacOS can support smart card logins, but on Intel Macs this may not work well with FileVault disk encryption since that needs the password to decrypt the disk. It’s possible m1/m2 based Macs solve this a different way. Macs may also have limited PIN support (numeric only).

Web authentication is also possible (most browsers support this) but the server needs to ensure the certificate is signed by the proper CA (same as with mTLS).

HOTP / TOTP / Static passwords

These three authenticators are lumped together since they use the same mechanism. Essentially the device acts as a USB keyboard and types the “secret”. This is very flexible. There is no PIN protection.

YubiKeys come with two slots. The first is accessed with a quick “short” press. The second requires a “long” press (maybe 3 seconds?). Since these are just “typing” they are not phishing resistant, and are just a “something you have” factor.

Each slot can be configured with HOTP/TOTP/Static credentials.

HOTP

“Out of the Box” slot 1 is configured with a Yubico managed HOTP seed. When you single press the device will “type” a one-time value that changes each time and adds the RETURN; eg

    cccccbbbubrtvbkjrrjhrkdgbcjfichivdihefvlujrt
    cccccbbbubrtrgndglnnltrcekljgnfibikhkrnvivrj

This value is documented, and Yubico provide an API for this built in seed.

The first part (cccccbbbubrt in this case) is the device identity; the remaining part of the value encodes things like “number of presses”.

Being HOTP the value changes each time you press, based on the number of times you’ve pressed. The validation server needs to keep track of the “last press” count for the device and only approve the login if the “new press” contains a count that is greater than the last value. This prevents replay attacks.

Using the built in seed it is possible to call the public Yubico API to validate the value. This is very simple, and even doable as a shell script.

It becomes very easy to create a self-service onboarding process. To register the device the user merely needs to tap the button (and so “type” the current code). The server can validate this (hence attest it is a YubiKey) via the Yubico API and save the device ID. For login the server simply needs to validate the code (again via the API) and verify the device ID matches the one saved.

This does have an external dependency on the Yubico servers being available in order to use this, but it provides a good and simple “out of the box” experience. You can use any off-the-shelf YubiKey (that supports HOTP) plug it in and self-register. We can be confident that it is a YubiKey being used; the call to the Yubico API verifies this is a YubiKey and not another device.

The seed can be replaced with a corporate owned one and you can run your own verification server, but then we have management complications (how to generate a unique seed for each device; how to ensure the device is a real YubiKey) so I don’t recommend this. I’d say that you should only do this if you’re worried about the Yubico server availability.

If the default seed is over-written then it can not be restored; only YubiKey can do this. If a “smart” (dumb) user uses the YubiKey manager (on a personal machine, for example) to delete the seed then they will no longer be able to use it for Yubico HOTP authentication.

TOTP

TOTP mode is similar to HOTP but uses “time based” rather than a count of touches. Since the YubiKey doesn’t have a built in clock it works in conjunction with the YubiKey Authenticator application. I think the authenticator app also stores an encrypted form of the TOTP seed (because of limited storage on the YubiKey, but I’m not sure of this). It will talk to the YubiKey and pass the time (and the encrypted seed? Not sure) to the YubiKey; the YubiKey performs the calculations and returns the current value to the app which the user can then type or copy/paste.

The problem with TOTP is in how the seed is copied; it’s generally exposed to the user (eg QR code) so they could screen shot it and add it to multiple authenticators. We also have no guarantee they are using a YubiKey and not some other program such as google authenticator. This makes it unsuitable for authentication for employees. Although I’ve seen similar mistakes with RSA SecurID softtokens

Static Passwords

And finally a slot can be configured for static passwords. I guess if you have a 28 character password then it might make sense? Storing a password in this way changes the password from “something you know” to “something you have” because possession of the YubiKey is all you need to use the password. Unfortunately we can’t stop a YubiKey being used this way, but this isn’t a problem unique to these devices; any “auto-typing” HID device could do this. We just have to trust people aren’t knowledgeable enough (or stupid enough) to do this. One YubiKey uniqueness, though, is that because the same device can possess the password and MFA (eg HOTP in slot 1 and password in slot 2) then MFA may be reduced to a single “have” factor; “long press for the password, short press for the MFA”. Yet another reason to move to passwordless!

PGP

I include this for completeness, because YubiKeys can support it. PGP is a tool for signing/encrypting email. It requires a public/private key. Typically these are stored on the filesystem, protected with passphrases.

With a YubiKey the private key can be generated/stored on the device and are protected with a PIN similar to PIV mode. This makes it possible to have stronger protections on this key.

However, many organisations need to have an enterprise managed encryption solution (potentially with a corporate master key) for legal and compliance reasons. Individuals using PGP would break that.

It is possible to configure some ssh clients to use gpg-agent (instead of ssh-agent) and so effectively use the YubiKey as a store for your ssh private key but it’s not a supported configuration on all clients, and I don’t think humans should use ssh keys to access servers unless you have strong management processes in place.

So, really, we might not want use this functionality for authentication.

Summary

This got long, because a YubiKey can do so much! Here’s a quick table of my conclusions.

U2F
Phish ResistantY
PasswordlessN
PIN ProtectedN
AttestableY
Authenticator Type"Have"
InterfacesPrimarily Browser
Suitability2nd factor if attested
FIDO 2
Phish ResistantY
PasswordlessY*
PIN ProtectedY*
AttestableY
Authenticator Type"Have" + "Know" (PIN)/"Are" (Biometric)
InterfacesBrowser, Desktop login
Suitability2nd factor if attested; passwordless if attested and UV enforced
PIV (Smart Card)
Phish ResistantY
PasswordlessY*
PIN ProtectedY
AttestableY
Authenticator Type"Have" + "Know" (PIN)
InterfacesBrowser, Desktop login
SuitabilityPasswordless if key generated on device
HOTP
Phish ResistantN
PasswordlessN
PIN ProtectedN
AttestableY*
Authenticator Type"Have"
InterfacesKeyboard typing
Suitability2nd factor with Yubico default seed
TOTP
Phish ResistantN
PasswordlessN
PIN ProtectedN
AttestableN
Authenticator Type"Have"
InterfacesKeyboard typing
SuitabilityNone
Static passwords
Phish ResistantN
PasswordlessN
PIN ProtectedN
AttestableN
Authenticator Type"Have"
InterfacesKeyboard typing
SuitabilityNone
PGP
Phish Resistantn/a
PasswordlessN
PIN ProtectedY
Attestablen/a
Authenticator Type"Have" + "Know" (PIN)
InterfacesOpenPGP
Suitabilityn/a

It’s important to note that this is just looking at what a YubiKey can provide. There are other solutions in this problem space, including applications on your mobile device that receive push notifications. Some of these just act as second factors, others can be completely passwordless.

However, sometimes you may not be able to use mobile devices (e.g. if you are in a call center where they’re not allowed in, or if you have employees who do not wish to install work related stuff on their personal devices).

In those scenarios a YubiKey or one of their competitors can provide a good strong solution. Just ensure you understand how to manage them and what their characteristics are.