Skip to content

Instantly share code, notes, and snippets.

@joostd
Created February 9, 2024 12:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joostd/ef34e52d17bbf546977ff8cfd61f38cd to your computer and use it in GitHub Desktop.
Save joostd/ef34e52d17bbf546977ff8cfd61f38cd to your computer and use it in GitHub Desktop.
Use the FIDO hmac-secret extension to generate a secret
# DEMO for hmac-secret - generate a static secret based on a FIDO credential and a salt
# Uses libfido2 tools: https://github.com/Yubico/libfido2
HID="$(shell fido2-token -L | head -1 | cut -d: -f1-2)"
all: secret
cred.in:
# challenge:
cat /dev/urandom | head -c32 | base64 > cred.in
echo relying party >> cred.in
echo user name >> cred.in
# userID:
cat /dev/urandom | head -c16 | base64 >> cred.in
# generate credential using hmac-secret extension
cred.out: cred.in
fido2-cred -M -h -i cred.in ${HID} > cred.out
# verify credential
cred: cred.out
cat cred.out | fido2-cred -V -h -o cred
pubkey: cred
tail -n +2 cred > pubkey
salt:
cat /dev/urandom | head -c32 > ./salt
assert.in: cred salt
# challenge:
cat /dev/urandom | head -c32 | base64 > assert.in
echo relying party >> assert.in
# credential ID:
head -1 cred >> assert.in
cat salt | base64 >> assert.in
# generate assertion using hmac-secret extension
assert.out: assert.in
fido2-assert -G -h -i assert.in ${HID} > assert.out
# verify assertion:
assert: assert.out pubkey
cat assert.out | fido2-assert -V -h pubkey es256
secret: assert.out
@/bin/echo -n "secret: "
@tail -1 assert.out
clean:
-rm assert.in assert.out cred.in cred.out cred pubkey salt
@joostd
Copy link
Author

joostd commented Feb 9, 2024

List FIDO security tokens:

$ fido2-token -L
ioreg://4295999846: vendor=0x1050, product=0x0406 (Yubico YubiKey FIDO+CCID)

Create an input file:

$ cat cred.in
IBBw/RGeV0NLRHAsx6UWnlBBYxe3qSDhVjxtxQCSbo0=
relying party
user name
BRP7tpJLrKbMxJdI8K2V3Q==

generate a FIDO credential using the hmac-secret extension:

$ fido2-cred -M -h -i cred.in "ioreg://4295999846" | fido2-cred -V -h -o cred
Enter PIN for ioreg://4295999846: 

The output looks like this:

$ cat cred
JmLaha+t8j5tTIXJl2cNGO6oDZs0TI653eqvUw3+pM+3+sYyHmYh5vxEWelFzeSIn6QNE0OdL5OVuFERJwPKaQ==
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzxvIBPiksyEl8ESrmXyt7z0ktTjh
yxb1vr3qNMoqNq1k1DSr7tr+tH3gMGYSgy8LcmTm6nrKA/F7KOV6sgWAJA==
-----END PUBLIC KEY-----

Create an input file to generate an assertion:

$ cat assert.in 
G2Uei6r1bIT8+VbsV/qk5M6EX3GsnJu78CZT2msJS7Y=
relying party
JmLaha+t8j5tTIXJl2cNGO6oDZs0TI653eqvUw3+pM+3+sYyHmYh5vxEWelFzeSIn6QNE0OdL5OVuFERJwPKaQ==
GrcK2TIW1uZllyWZrsLN8Zbu/488Gdv2kR8N9K7N7NA=

Generate an assertion, using the hmac-secret extension:

$ fido2-assert -G -h -i assert.in "ioreg://4295999846" > assert.out

Optionally, verify the assertion:

$ cat assert.out | fido2-assert -V -h pubkey es256

The output looks like this:

$ cat assert.out 
G2Uei6r1bIT8+VbsV/qk5M6EX3GsnJu78CZT2msJS7Y=
relying party
WGSusDiEl8jD03XBV+5yBpiseHi+hwrY8aqZNy+sXbRbVIEAAAAFoWtobWFjLXNlY3JldFgwi/NhDo+uLcaAMOsih6ELEZThx819w/4IXyQyK8oV5mCtHuSQZAGDDLvFrN+vJUTI
MEQCIAljgeLp9GaELTvkje0JVvXflPpgK9UPUpivIcKjt74pAiBjeDVgjwklrIjE0h19DRpQz1ZTFx2hymz9LcdYVm6L1w==
NFBoVuu3qrnJT3DftAeWoDCAtqIeJ5FF5dcdaoquQvY=

The last line of this file contains your secret:

NFBoVuu3qrnJT3DftAeWoDCAtqIeJ5FF5dcdaoquQvY=

Note: Some YubiKeys (such as the YubiKey Bio) have an option alwaysUV enabled by default. When that option is enabled, UV is always required and you need to instruct fido2-assert to ask for the PIN as follows:

$ fido2-assert -G -h -t pin=true -i assert.in "ioreg://4295999846"

If you do not want UV for creating assertions, you can disable the alwaysUV option as follows:

$ ykman fido config toggle-always-uv                                        
Enter your PIN: 
$ ykman fido info                                                           
PIN:                          8 attempt(s) remaining
Minimum PIN length:           6
Fingerprints:                 not registered
Always Require UV:            off
Credential storage remaining: 25

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment