In the last few months there has been a lot of hype about "passkeys" and how they are going to change authentication forever. But that hype will come at a cost.

Obsession with passkeys are about to turn your security keys (yubikeys, feitian, nitrokeys, ...) into obsolete and useless junk.

It all comes down to one thing - resident keys.

What is a Resident Key

To understand the problem, we need to understand what a discoverable/resident key is.

<aside> ℹ️ non-resident or non-discoverable credential:

  1. 用户把 security key 的 pubkey 上传给 relying party(RP,认证服务器),作为自己的身份标识。(类似于 SSH 的 pubkey)
  2. authentication 时,relying party 生成一对公私钥,然后用用户的 security key pubkey 加密 privkey。再生成一段随机内容作为 challenge。将 encrypted prikey 和 challenge 一起发送给用户。
  3. 用户用 security key privkey 解密 challenge,获取 privkey。用 privkey 签名 challenge,返回给 relying party。
  4. relying party 用 pubkey 校验签名,确认用户确实解密获取了 privkey。

</aside>

You have probably seen that most keys support an 'unlimited' number of accounts. This is achieved by sending a "key wrapped key" to the security key. When the Relying Party (Authentication Server) wants to authenticate your security key, it will provide you a "credential id". That credential ID is an encrypted blob that only your security key can decrypt. If your security key can decrypt that blob it yields a private key that is specific to that single RP that you can use for signatures.

┌────────────────┐            ┌────────────────┐          ┌────────────────┐
│ Relying Party  │      │     │    Browser     │     │    │  Security Key  │
└────────────────┘            └────────────────┘          └────────────────┘
                        │                            │
     1. Send
   Credential ──────────┼───────▶                    │
       IDs
                        │      2. Forward to─────────┼─────▶   3. Decrypt
                               Security Key                   Credential ID
                        │                            │       with Master Key
                                                                    │
                        │                            │              │
                                                                    │
                        │                            │              ▼
                                                            4. Sign Challenge
                        │                            │       with Decrypted
                                                                   Key
                        │                            │              │
                                                                    │
                        │                            │              │
                                                                    ▼
                        │          6. Return  ◀──────┼───────── 5. Return
                 ◀──────────────── Signature                    Signature
                        │                            │

This is what is called a non-resident or non-discoverable credential. The reason is that the private key can not be discovered by the security key without the Credential ID provided to it externally. This is because the private keys are not resident inside the security enclave - only the master key is.

<aside> ℹ️ 作为对比,a resident key or discoverable credential 就是不采用 key-wrapped-key 的形式,而是直接用 security key 里的 privkey 签名 challenge。 所以在这种情况下,将 security key 内的 privkey 称为 resident key

相较之下,使用 resident key 的优点在于,用户不需要输入用户名了。

</aside>

Contrast to this, a resident key or discoverable credential is one where the private key is stored in the security key itself. This allows the security key to discover (hence the name) what private keys might be used in the authentication.

┌────────────────┐            ┌────────────────┐          ┌────────────────┐
│ Relying Party  │      │     │    Browser     │     │    │  Security Key  │
└────────────────┘            └────────────────┘          └────────────────┘
                        │                            │
  1. Send Empty
   CredID list──────────┼───────▶                    │
                                 2. Query  ───────────────▶
                        │      Security Key          │      3. Discover Keys
                                                                 for RP
                        │       4. Select a ◀────────┼─────
                               Security Key
                        │                   ─────────┼────▶ 5. Sign Challenge
                                                            with Resident Key
                        │                            │             │
                                                                   │
                        │                            │             │
                                                                   ▼
                        │         7. Return  ◀───────┼──────── 6. Return
                ◀──────────────── Signature                    Signature
                        │                            │
                        │                            │
                        │                            │

Now, the primary difference here is that resident/discoverable keys consume space on the security key to store them since they need to persist - there is no credential id to rely on to decrypt with our master key!

Are non-resident keys less secure?

A frequent question here is if non resident keys are less secure than resident ones. Credential ID's as key wrapped keys are secure since they are encrypted with aes128 and hmaced. This prevents them being tampered with or decrypted by an external source. If aes128 were broken and someone could decrypt your private-key in abscence of your security key, they probably could also break TLS encyrption, attack ssh and do much worse. Your key wrapped keys rely on the same security features that TLS relies on.

How does userverification factor in here?

Another frequent question (or confusion) is that a credential needs to be resident to enforce userVerification. That's not the case! Your device can assert not just presence by touch, but that it's really you holding the device by internally validating a PIN or biometric. This is governed by the userVerification flags which are seperate to residency. This allows your device to be "a self contained multifactor authenticator". Very cool!

Resident Keys and Your Security Key

Now that we know what a resident key is, we can look at how these work with your security keys.

<aside> ℹ️ security key 设备上支持持久化 resident key 的 slots 是有限的

</aside>