To be secure, it is recommended to use a separate implementation for server and client.
- create
Challenge
Correct implementation is done on the server side.
let challenge = verifier::create_challenge();- create
MakeCredentialArgs
- need
rpid(string)andchallenge - set
pin(string)
let make_credential_args = MakeCredentialArgsBuilder::new(&rpid, &challenge)
.pin(pin)
.build();- create
FidoKeyHid
let device = FidoKeyHidFactory::create(&cfg)?;- get
AttestationObject
let attestation = device.make_credential_with_args(&make_credential_args)?;- verify
AttestationObject
Correct implementation is done on the server side.
- need
rpid(string)andchallengeandAttestation
let verify_result = verifier::verify_attestation(rpid, &challenge, &attestation);
if verify_result.is_success {
println!("-- Verify Attestation Success");
} else {
println!("-- ! Verify Attestation Failed");
}- store Credential Id and Publickey
Correct implementation is done on the server side.
let userdata.credential_id = verify_result.credential_id;
let userdata.credential_public_key = verify_result.credential_public_key;
store(&userdata); <- ex.store to database- restore Credential Id and Publickey
Correct implementation is done on the server side.
let userdata = restore(userid); <- ex.restore from database
userdata.credential_id;
userdata.credential_public_key;- create
Challenge
Correct implementation is done on the server side.
let challenge = verifier::create_challenge();- create
GetAssertionArgs
- need
rpid(string)andchallenge - set
pin(string)and Credential Id
let get_assertion_args = GetAssertionArgsBuilder::new(rpid, &challenge)
.pin(pin)
.credential_id(&userdata.credential_id)
.build();- get
AssertionObject
let assertions = device.get_assertion_with_args(&get_assertion_args)?;- verify
AssertionObject
Correct implementation is done on the server side.
- need
rpid(string)and PublicKey andchallengeandAssertion
let is_success = verifier::verify_assertion(
rpid,
&userdata.credential_public_key,
&challenge,
&assertions[0],
);
if is_success {
println!("-- Verify Assertion Success");
} else {
println!("-- ! Verify Assertion Failed");
}-
non-discoverable credentials/non-resident-key
- Most common use to specify PIN.
-
- to use Yubikey bio for fingerprint authentication.
-
- Specify the algorithm(
Ecdsa256/Ed25519).
- Specify the algorithm(
-
with HMAC Secret Extension (use optional salt)
- I do not know the correct use of this option.
-
- Used with Large Blob Command.
- Spec: 6.10.5. Writing per-credential large-blob data for a new credential
-
- Get Min Pin Length Policy.
- RPID must be set in Authenticator Config. → Authenticator Config
- Spec: 12.4. Minimum PIN Length Extension (minPinLength)
-
-
For security reasons, this feature is deprecated
-
Use
without_pin_and_uvto run with an Authenticator that does not have a PIN set. -
Using
without_pin_and_uvon an Authenticator with a PIN set may result in an error (behavior depends on Authenticator type). -
Get whether PIN is set in Authenticator with
enable_info_option()
-
-
- use
device.set_pin_uv_auth_protocol_two().
- use
- discoverable credentials/resident-key
- User data can be stored in the authenticator.
- user_name and user_display_name are set only when multiple Assertions are acquired.
- with Credential Blob Extension
- This extension enables RPs to provide a small amount of extra credential configuration.
- This extension only works if CTAP 2.1 is implemented.
Legacy patterns are deprecated. They will be removed in a future version.