You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Licensed under the Apache License, Version 2.0 (the "License");
8
8
you may not use this file except in compliance with the License.
@@ -16,112 +16,155 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
16
See the License for the specific language governing permissions and
17
17
limitations under the License. -->
18
18
19
-
# FIDO2 HMAC secret ("hmac-secret" extension)
19
+
# FIDO2 hmac-secret and hmac-secret-mc extensions
20
20
21
-
When you get the [AuthenticatorInfo](xref:Yubico.YubiKey.Fido2.AuthenticatorInfo), you can
22
-
check the extensions to see if "hmac-secret" is supported.
21
+
The SDK and YubiKey (depending on firmware version) support the hmac-secret and hmac-secret-mc extensions, which enable the creation of a symmetric secret value scoped to a credential. This secret, which can be used for encryption and decryption, supports the use of WedAuthn's [Pseudo-Random Function (PRF)](https://developers.yubico.com/WebAuthn/Concepts/PRF_Extension/index.html) with YubiKeys.
22
+
23
+
When requested, the YubiKey generates the hmac secret by performing HMAC with SHA-256 using
24
+
the secret value it has associated with the credential as the key plus one or two salts provided
25
+
by the client. It then encrypts the result (returned as a byte array) using the ECDH-derived shared secret key (the key used to encrypt all communications between the client and the YubiKey). The hmac secret can only be requested during ``MakeCredential()`` (hmac-secret-mc) or ``GetAssertions()`` (hmac-secret).
26
+
27
+
hmac-secret and hmac-secret-mc are supported for both discoverable and non-discoverable credentials.
28
+
29
+
## Salts
30
+
31
+
The client must provide one or two 32-byte salts to the YubiKey when requesting the secret. If one salt is provided, the YubiKey will return a secret value of 32 bytes in length; if two salts are provided, the YubiKey will return two secret values, each 32 bytes in length.
32
+
33
+
According to the [CTAP standard](https://fidoalliance.org/specs/fido-v2.2-ps-20250714/fido-client-to-authenticator-protocol-v2.2-ps-20250714.html#sctn-hmac-secret-extension), the second secret value returned in the two-salt scenario "can be used when the platform wants to roll over the symmetric secret in one operation."
34
+
35
+
## hmac-secret vs hmac-secret-mc
36
+
37
+
The fundamental difference between the hmac-secret and hmac-secret-mc extensions is when the secret is returned by the YubiKey.
38
+
39
+
With hmac-secret, the secret is returned during ``GetAssertions()``. However, with hmac-secret-mc, the secret is returned during ``MakeCredential()``.
40
+
41
+
hmac-secret-mc is useful in situations where the secret is needed immediately upon creation of a new credential. By returning the secret in a single operation instead of two (``MakeCredential()`` followed by ``GetAssertions()``), the amount of user interaction required, including user presence and PIN/UV validation, is reduced.
42
+
43
+
## Verify support for hmac-secret and hmac-secret-mc
44
+
45
+
The hmac-secret-mc extension is only supported for YubiKeys with firmware version 5.8 and later. To verify whether a particular YubiKey supports the hmac-secret and hmac-secret-mc extensions, check the key's [AuthenticatorInfo](xref:Yubico.YubiKey.Fido2.AuthenticatorInfo):
23
46
24
47
```C#
25
-
using (fido2Session=newFido2Session(yubiKeyDevice))
48
+
using (fido2Session=newFido2Session(yubiKey))
26
49
{
27
-
if (fido2Session.AuthenticatorInfo.Extensions.Contains<string>("hmac-secret"))
50
+
if (fido2Session.AuthenticatorInfo.IsExtensionSupported(Extensions.HmacSecret))
If it is, when making a credential you can specify that the YubiKey create a secret value
35
-
associated with that credential. Later on when getting an assertion, you can ask the
36
-
YubiKey to retrieve that secret. What you do with that secret is up to you. The standard
37
-
remarks that it can be used to encrypt or decrypt data.
61
+
## Enabling the hmac-secret extension and requesting the secret
38
62
39
-
Each client will have access to this secret value, so that it is possible to securely
40
-
share information among clients. The secret value is actually built from a value on the
41
-
YubiKey and a salt provided by the client. The standard says, "The authenticator and the
42
-
platform each only have the part of the complete secret to prevent offline attacks."
43
-
Hence, for all clients to share this secret, each client must use the same salt.
63
+
With hmac-secret, the extension needs to be enabled for a credential during ``MakeCredential()`` in order to return the secret during ``GetAssertions()``. It is not possible to add the extension to an existing credential.
44
64
45
-
## Requesting the YubiKey create this secret
46
-
47
-
The YubiKey will generate a secret for a credential only if instructed to do so at the
48
-
time the credential is made. It is not possible to "add" this secret to an existing
49
-
credential.
65
+
To enable the hmac-secret extension, we must add it to the parameters for MakeCredential prior to calling the ``MakeCredential()`` method:
50
66
51
67
```csharp
52
-
using (fido2Session=newFido2Session(yubiKeyDevice))
When getting an assertion, you specify you want the YubiKey to return the assertion and
64
-
the secret value. If you don't, the YubiKey will return the assertion, but it won't return
65
-
the secret.
91
+
Once the extension has been added to a credential, we can return the secret with ``GetAssertions()``. However, we must first add the request for the secret along with the salt(s) to the parameters for GetAssertion via ``RequestHmacSecretExtension(salt1, salt2)``. Providing a second salt is not required.
66
92
67
93
```csharp
68
94
using (fido2Session=newFido2Session(yubiKeyDevice))
The secret will be returned in the ``GetAssertionData``.
112
+
113
+
## Enabling the hmac-secret-mc extension and requesting the secret
78
114
79
-
Once you have an assertion, you will find the secret in the `Extensions`in the
80
-
`GetAssertionData.AuthenticatorData` property. There is a method in that class that will
81
-
parse and decrypt the value returned.
115
+
With hmac-secret-mc, the extension needs to be enabled for a credential during ``MakeCredential()``*and* the salt(s) must be provided in order to return the secret. To do so, we must add the extension and salt(s) to the parameters for MakeCredential prior to calling the ``MakeCredential()`` method.
116
+
117
+
If the operation is successful, the secret will be returned in the ``MakeCredentialData``.
82
118
83
119
```csharp
84
-
using (fido2Session=newFido2Session(yubiKeyDevice))
Once the secret has been returned, we can extract and decrypt it using the ``AuthenticatorData.GetHmacSecretExtension()`` method.
107
147
108
-
It is possible to pass in two 32-byte salts to the
109
-
`GetAssertionParameters.RequestHmacSecretExtension` method. In that case, the YubiKey will
110
-
return two values. The standard says the second value is used "...when the platform wants
111
-
to roll over the symmetric secret...".
148
+
If the secret was generated using one salt, the result will be a 32-byte value. In the case of two salts, the result will be 64 bytes in length, with the first 32 bytes representing the value generated with `salt1` and the second 32 bytes representing the value generated with `salt2`.
149
+
150
+
To perform the extraction and decryption on ``GetAssertionData`` (hmac-secret), perform an operation like shown in the following code sample. Note that if authenticator data was returned for more that one credential, we must specify which credential's secret we'd like to extract.
112
151
113
152
```csharp
114
-
using (fido2Session=newFido2Session(yubiKeyDevice))
The result will be an array 64 bytes long. The first 32 bytes make up the result based on
127
-
`salt1`, and the second 32 bytes make up the result based on `salt2`.
162
+
For extraction and decryption on ``MakeCredentialData`` (hmac-secret-mc), we do not need to specify a particular credential given that only one was created at the time the secret was returned:
Copy file name to clipboardExpand all lines: docs/users-manual/getting-started/whats-new.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -62,7 +62,7 @@ Features:
62
62
63
63
- thirdPartyPayment extension: The [GetThirdPartyPaymentExtension](xref:Yubico.YubiKey.Fido2.AuthenticatorData.GetThirdPartyPaymentExtension) method has been added to check for and return the status of the thirdPartyPayment extension. The thirdPartyPayment extension enables YubiKeys to be used for cross-domain credentials without redirects, as required by Secure Payment Confirmation (SPC) workflows.
64
64
65
-
- hmac-secret-mc extension: [GetHmacSecretExtension](xref:Yubico.YubiKey.Fido2.AuthenticatorData.GetHmacSecretExtension%28Yubico.YubiKey.Fido2.PinProtocols.PinUvAuthProtocolBase%29) now handles both hmac-secret and hmac-secret-mc extensions when extracting and decrypting secrets. The hmac-secret-mc extension enables PRF (Pseudo-Random Function) during [MakeCredential()](xref:Yubico.YubiKey.Fido2.Fido2Session.MakeCredential%28Yubico.YubiKey.Fido2.MakeCredentialParameters%29).
65
+
-[hmac-secret-mc extension](xref:Fido2HmacSecret): This extension enables the retrieval of a symmetric secret during ``MakeCredential()``. The secret, which can be used for encryption/decryption, supports the use of PRF (Pseudo-Random Function) with YubiKeys.
66
66
67
67
- Additional ``AuthenticatorInfo`` properties: The SDK now supports parsing of several new [AuthenticatorInfo](xref:Yubico.YubiKey.Fido2.AuthenticatorInfo) properties, which are returned when calling the [GetInfoCommand()](xref:Yubico.YubiKey.Fido2.Commands.GetInfoCommand). Properties include ``AttestationFormats``, ``UvCountSinceLastPinEntry``, ``LongTouchForReset``, ``EncIdentifier``, ``TransportsForReset``, ``PinComplexityPolicy``, ``PinComplexityPolicyUrl``, and ``MaxPinLength``.
0 commit comments