ASP.NET Core 5.0 - Multiple FIDO2 Credentials

Ken Haggerty
Created 08/16/2021 - Updated 08/16/2021 04:02 GMT

This article will demonstrate management of multiple FIDO2 devices in the Users Without Passwords Project (UWPP). I will assume you have downloaded the ASP.NET Core 5.0 - Users Without Passwords Project.

Users Without Passwords Project and Article Series

I have developed two separate projects in the Users Without Passwords Project (UWPP) solution. The Users Without Passwords v4 project supports Bootstrap v4 and the new Users Without Passwords project supports Bootstrap v5. The new version is published at Fido.KenHaggerty.Com. You can register a new user with Windows Hello or a FIDO2 security key. Details, screenshots, and related articles can be found at ASP.NET Core 5.0 - Users Without Passwords Project. The details page includes the version change log.

An early objective was to implement multiple credentials and credential management per user. At the time, my first FIDO2 device was a yubico Security Key NFC and my second FIDO2 device was Windows Hello. The yubico security key uses Elliptic Curve cryptography and Windows Hello uses RSA cryptography. With the help of GitHub - passwordless-lib / fido2-net-lib, I implemented RSA cryptography. The UWPP configures a list of AllowCredentials, including Transport hints, which are all the Credential Ids related to the user before the user calls the navigator. credentials. get() function from JavaScript during the log in or assertion ceremony. See ASP.NET Core 5.0 - Credential Get.

Credentials Add Backup Device
Credentials Add Backup Device Mobile

When the user adds a new credential, the ExcludedCredentials list is used by the attestation ceremony and excludes known authenticators.

CredentialChallenge.cshtml.cs > OnGetAsync:
// 5.4
// excludeCredentials, of type sequence<PublicKeyCredentialDescriptor>, defaulting to []
var excludeCredentials = new List<ExcludedCredential>();
var credentialIds = await _credentialService.GetCredentialIdsByAppUserIdAsync(AppUserId);
if (credentialIds.Count == 0)
    throw new InvalidOperationException($"No Credentials found for AppUser.Id = {AppUserId})");
foreach (var cid in credentialIds)
    excludeCredentials.Add(new ExcludedCredential()
        Type = _challengeOptions.CredentialType,
        Id = cid
CredentialChallenge.cshtml > JavaScript:
let createOptions = @@Html.Raw(Model.CreateOptions);
CredentialChallenge.cshtml > createCredential:
// Update byte string to expected Uint8Array
try {
    if (typeof (createOptions.challenge) != Uint8Array)
        createOptions.challenge = getUint8Array(createOptions.challenge);

    if (typeof ( != Uint8Array) = getUint8Array(;

    let l = createOptions.excludeCredentials.length;
        for (let i = 0; i < l; i++)
            if (typeof (createOptions.excludeCredentials[i].id) != Uint8Array)
                createOptions.excludeCredentials[i].id = getUint8Array(createOptions.excludeCredentials[i].id);

} catch (e) {
    showMessageModal(e, 'alert-warning');
New Credential Challenge
New Credential Challenge Mobile

The UWPP implements credential management with a primary credential and editable credential name.

Manage Multiple Credentials
Manage Multiple Credentials Mobile

The user can delete non primary credentials.

Confirm Delete Credential
Confirm Delete Credential Mobile

Administrators can manage credentials by user.

Admin AppUser Index
Admin AppUser Index Mobile
Admin AppUser
Admin AppUser

Article Tags:

Authorization FIDO Modal
Successfully completed. Thank you for contributing.
Contribute to enjoy content without advertisments.
Something went wrong. Please try again.



No Comments Found


Not accepting new comments.

Submit your comment. Comments are moderated.

User Image
DisplayedName - Member Since ?