how to delete passkeys windows 10 coverPasskeys User Tips

How to Delete Passkeys on Windows 10

Learn how to delete passkeys on Windows 10 using certutil & other tools to enhance Windows Hello. Follow our guide to manage WebAuthn credentials effectively.

Blog-Post-Author

Vincent

Created: May 14, 2024

Updated: August 27, 2024


Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.

  1. Introduction: How to Delete Passkeys on Windows?

  2. How to Activate Passkeys on Windows 10?

    2.1 How to Set a PIN for Windows Hello in Windows 10?

    2.2 How to Verify if Windows Hello is Activated?

    2.3 For Developers: How to Effectively Test Passkeys on Windows 10?

  1. How to List & Analyze Passkeys on Windows 10?

    3.1 Where does Windows Hello Store Passkeys?

      3.1.1 Key Storage Locations

      3.1.2 How WebAuthn Credentials are Managed

      3.1.3 Security Measures

    3.2 How to Use Certutil to List & Analyze Passkeys on Windows 10?

      3.2.1 How to List All Available Passkeys on Windows 10?

      3.2.2 Windows 10 PC (Intel CPU): certutil output

      3.2.3 Windows 11 VM (Parallels on ARM-Mac): certutil output

  1. How to Delete Passkeys on Windows 10?

    4.1 Deleting Passkeys with Command Line Tool certutil

    4.2 Deleting Passkeys with webauthn-fido2-key-remover

      4.2.1 Using the Latest Release from webauthn-fido2-key-remover Directly

      4.2.2 Using Latest webauthn-fido2-key-remover Version from Corbado

  1. Recommendation

  2. Conclusion

1. Introduction: How to Delete Passkeys on Windows?#

At Corbado, we are developing a Passkey-First authentication solution. Many passkey challenges come from using passkeys on Windows 10. Windows 10 offers device-bound passkeys, but the operating system lacks the ability to manage passkeys via a UI.

Subreddit Icon

Discuss passkeys news and questions in r/passkey.

Join Subreddit

As the number of passkeys increases within the Windows 10 authenticator, Windows Hello becomes slower and slower, which is especially unproductive for developers. In this article, we will:

  • Make a short deep dive into Windows 10 WebAuthn cryptography: We will examine how Windows 10 handles WebAuthn cryptography and where FIDO2 credentials are generally stored on Windows 10. We will start by activating Windows Hello and ensuring it is set up correctly.

  • Find out how to manage and remove passkeys on Windows 10: We will go through the possibilities for listing and identifying passkeys and WebAuthn credentials locally. At the end, we will discuss how to remove them.

When having to deal with a lot of credentials, command line tools are not enough. Therefore, we have extended the webauthn-fido2-key-remover, an open-source tool to help identify and delete passkeys more comfortably with multiple domains and multiple passkeys per domain.

2. How to Activate Passkeys on Windows 10?#

Before we start deleting passkeys, we will go through some basics of Windows 10 cryptography with passkeys. To activate passkeys on Windows 10, the Windows Hello authenticator needs to be activated. Since Windows 10 can operate without a hardware security module (TPM), it can store passkeys within a software-based HSM. However, this method is not as secure as using a physical HSM, which is required for Windows 11.

2.1 How to Set a PIN for Windows Hello in Windows 10?#

If you are working on a system where you are not sure if Windows Hello is activated, you can check on https://state-of-passkeys.io for passkey-readiness. If Windows Hello is activated, the check for passkey-ready should hold true:

Test Passkey Readiness

In case you wonder why Conditional UI works without a platform authenticator (as in the screenshot), you need to know that this behavior can occur on Chrome browsers. Chrome started to return true for Conditional-UI-readiness with version 123 (due to privacy considerations). To activate Windows Hello, open the settings in Windows 10 and navigate to “Sign-in options”. Start by adding a Windows Hello PIN:

Activate Windows Hello Passkeys

Create PIN Windows Hello Passkeys

Depending on your Windows version, this might look slightly different. After entering the current account password, the PIN can be added. You can continue to add further biometric login methods like "Windows Hello Face" or "Windows Hello Fingerprint," but they are not necessary to activate Windows Hello. They are both shortcuts for the actual PIN. In case a Microsoft account is used with the computer, other forms of verification might be triggered.

2.2 How to Verify if Windows Hello is Activated?#

Verify that Windows Hello has been successfully activated on https://state-of-passkeys.io/ you should see something like this now:

Full Passkey Readiness Test

It is important that not only the WebAuthn API is available and active (“WebAuthn-ready”) but also “Passkey-ready” is true. For checking the passkey-readiness, the browser is queried via PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() and returns true if a platform authenticator ( Windows Hello) is available.

2.3 For Developers: How to Effectively Test Passkeys on Windows 10?#

Windows 10 will not get feature updates anymore but still gets security updates and dominates the desktop market as of May 2024. Our prediction is that Windows 10 will be a major player in the desktop OS market until 2027. Recent statistics released by statcounter even showed that Windows 10 market share increased slightly for two months in a row. Therefore, testing on Windows including version 10 is extremely important for any passkey-based application. You have the following options for testing:

  • Option 1 - Windows 10 PC (our recommendation): Actually have a real Windows 10 installation in order to have the most realistic experience and see how the actual UI looks. Of course, the best way to test is to actually be developing on Windows 10 but depending on the Enterprise among Frontend-heavy and Native-App focused companies Macs often dominate.

  • Option 2 - Windows 10 VM on macOS: In case you have an Intel-based macOS device, you can install a Windows 10 image into a simulator like Parallels, but this needs some more effort as this is not officially supported anymore.

  • Option 3 - Windows 11 VM on macOS: This works very well for a generic feeling of how Windows feels like with the latest version of Chrome. Actual compatibility settings cannot be tested as Windows 11 has a newer Windows Hello version which also includes Cross-Device-Authentication natively, which Windows 10 does not.

At Corbado, we have product managers who volunteered to continue to use Windows 10 as their primary working environment to get an authentic experience of passkeys on Windows 10. As they do not necessarily need to run a full docker system locally that developers might need and which performs better on macOS, it is the best way for us to keep our device coverage. In addition, we have some spare Windows 10 computers for developer testing.

3. How to List & Analyze Passkeys on Windows 10?#

In this section, we will find out how we can list all registered passkeys on a Windows 10 system.

Substack Icon

Subscribe to our Passkeys Substack for the latest news, insights and strategies.

Subscribe

3.1 Where does Windows Hello Store Passkeys?#

Windows Hello on Windows 10 stores passkeys and WebAuthn credentials in a secure, system-protected location within the operating system. These credentials are stored in a similar manner to other cryptographic keys and certificates used for authentication and encryption purposes. As we have outlined in the introduction, Windows 10 is prepared to do so even without a HSM in form of an TPM, as this is not a hardware requirement for Windows 10. Here are the different approaches and options for storage:

3.1.1 Key Storage Locations#

3.1.1.1 Local Security Authority (LSA) Secrets#

Windows Hello utilizes the Local Security Authority (LSA) to manage sensitive information such as cryptographic keys and user credentials. LSA Secrets are stored in the Windows registry under HKEY_LOCAL_MACHINE\Security\Policy\Secrets.

These secrets are protected by the LSA and can only be accessed by privileged system processes, making them secure from unauthorized access.

3.1.1.2 Credential Store#

Windows 10 also leverages the Credential Manager to store user credentials. This includes WebAuthn credentials that are created when users register passkeys through their browsers or applications.

The Credential Manager stores these credentials in an encrypted format within the Credential Store, which is located in %SystemRoot%\System32\config\systemprofile\AppData\Local\Microsoft\Credentials.

3.1.1.3 Protected User Mode (PUM) and TPM#

On systems equipped with a Trusted Platform Module (TPM), Windows Hello can utilize the TPM to provide additional security. The TPM is a hardware-based security feature that securely generates, stores, and manages cryptographic keys.

On systems without a TPM, Windows 10 uses a software-based approach to emulate similar security functions, storing cryptographic keys securely within the system.

Slack Icon

Become part of our Passkeys Community for updates and support.

Join

3.1.2 How WebAuthn Credentials are Managed#

3.1.2.1 Credential Creation:#

When a user registers a new WebAuthn credential, a key pair (public and private keys) is generated. The private key is securely stored on the device (in the LSA Secrets or TPM), while the public key is sent to the authenticating server.

The public key, along with a unique credential ID, is associated with the user's account on the server.

3.1.2.2 Credential Access#

During authentication, the system retrieves the appropriate private key from the secure storage. The user is prompted to verify their identity (e.g., via PIN, fingerprint, or facial recognition).

Once verified, the private key is used to sign a challenge provided by the server, proving the user's identity without exposing the private key itself.

3.1.3 Security Measures#

  • Encryption: All stored credentials and keys are encrypted, ensuring they are protected from unauthorized access even if an attacker gains physical access to the storage medium.

  • Access Controls: Access to the stored credentials is tightly controlled by the operating system, with only privileged processes having the ability to read or modify them.

  • Attestation: Windows Hello supports attestation, which allows the device to prove to the server that it holds a genuine key generated by a trusted platform.

In summary, Windows 10 uses a combination of the LSA, Credential Manager, and optionally TPM, to securely store and manage WebAuthn credentials and passkeys. These components work together to ensure that user credentials are protected by strong encryption and access control mechanisms, providing a secure authentication experience.

3.2 How to Use Certutil to List & Analyze Passkeys on Windows 10?#

After activating Windows Hello on the device, we went on and created a passkey on https://state-of-passkeys.io. In this section, we will list the created passkeys and explain more details of them.

3.2.1 How to List All Available Passkeys on Windows 10?`#

To list credentials on the system with existing tools, the command line tool certutil has to be used:

Command:

certutil -csp NGC -key -v

The command certutil -csp NGC -key -v involves the use of certutil, a command-line utility for managing certificates in Windows. Here’s a breakdown of the command:

  1. certutil: This is the command-line utility provided by Windows for certificate management tasks. It allows users to perform various operations related to certificates, including creation, verification, and management of certificate stores.

  2. -csp NGC: This specifies the Cryptographic Service Provider (CSP) to be used. CSPs are libraries that implement cryptographic algorithms and manage keys. NGC (Next Generation Credentials) refers to a CSP associated with the Next Generation Credentials framework. NGC was introduced by Microsoft to enhance authentication mechanisms in Windows, especially starting from Windows 10. It is part of Microsoft's move towards more secure and user-friendly authentication methods, such as Windows Hello for Business, which includes biometric and PIN-based logins.

  3. -key: This option is used to perform operations related to cryptographic keys. It can include tasks like key generation, listing, or deletion.

  4. -v: This stands for verbose mode, which provides detailed output of the command's execution process. It’s useful for debugging or understanding the steps being performed.

3.2.2 Windows 10 PC (Intel CPU): certutil output#

Let’s run this command on a native Windows 10 machine after we created a passkey on https://state-of-passkeys.io/.

Command:

certutil -csp NGC -key -v

Output:

S-1-5-21-3027362018-461445109-2096225366-1001/a4647d39-e794-4db7-bf79-1f672b0b7e6c/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5459794d44517a4d6a6b344e7a55794d7a49794e7a41344e6a51 RSA Key Id Hash (rfc-sha1): 02c300e2bedbcb6a743ca7d6a7b63c6705f836fa Key Id Hash (sha1): cbd8ad3cc05402afa0bb176708346aea53408832 Key Id Hash (bcrypt-sha1): 23b1cdc3061fc99fbac25be437ad8f7aa807e228 Key Id Hash (bcrypt-sha256): d486770fd7e9f5c9c84a00d590ed36c5b39b1798bc32f7974c3cb2ef359d3c0b Container des öffentlichen Schlüssels: 0000 30 82 01 0a 02 82 01 01 00 9f 4d 82 57 81 6c 94 0010 7f b4 51 80 8c 2b fc eb e8 94 a5 9b 57 45 6a 41 0020 f0 83 7b 9a 53 31 0e 22 82 82 2e 04 63 ac 77 47 0030 b5 70 08 77 72 e9 64 f4 fc 00 f5 2d 07 b8 b9 e1 0040 d2 54 f4 f2 fc 39 d5 75 a1 3f 4a 30 20 6f 68 81 0050 89 44 31 60 86 98 2b d2 5e 4b 44 f4 01 06 19 4a 0060 c4 04 19 67 bc c6 dd 0e 60 c6 6f eb 30 fe 63 c7 0070 55 62 5f 45 71 5d 48 91 c2 8d 3f 54 26 40 4d 2e 0080 36 64 6a 55 7e 0a 1a 9e f0 60 85 75 13 25 c1 d1 0090 d4 db 44 75 65 41 d4 01 a0 be 9e c6 df 47 c0 5e 00a0 a3 b3 1d 60 45 f2 02 3c 6f e3 56 f0 71 83 af a5 00b0 d9 ed 89 b4 43 34 fa 04 7d d1 00 95 d6 44 1b 75 00c0 02 cb b4 b7 95 bc f2 2d 25 b6 f0 3a 85 d4 ba 1d 00d0 57 75 e5 e5 49 a6 54 c3 b7 1d 8d f7 a1 e8 76 84 00e0 98 b3 d4 73 3c 35 c7 00 09 0c ec 3f 7a a0 8b 3e 00f0 92 de 6b f5 ab 96 42 69 4b d7 3e b6 9f d9 fd 4a 0100 c2 4a 15 9b d3 b4 fe 81 c5 02 03 01 00 01 Cached Key Identifier: S-1-5-21-3027362018-461445109-2096225366-1001/a4647d39-e794-4db7-bf79-1f672b0b7e6c/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5459794d44517a4d6a6b344e7a55794d7a49794e7a41344e6a51: No container name match. Cached Key Identifier: S-1-5-21-3027362018-461445109-2096225366-1001/a4647d39-e794-4db7-bf79-1f672b0b7e6c/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5459794d44517a4d6a6b344e7a55794d7a49794e7a41344e6a51: No KeyId match. NCRYPT_ALLOW_DECRYPT_FLAG -- 1 NCRYPT_ALLOW_SIGNING_FLAG -- 2 (NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4) (NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8) (NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)) UI Policy = 0 (NCRYPT_UI_PROTECT_KEY_FLAG -- 1) (NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG -- 2) Version: 0 Export Policy = 0 (NCRYPT_ALLOW_EXPORT_FLAG -- 1) (NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2) (NCRYPT_ALLOW_ARCHIVING_FLAG -- 4) (NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8) Name: S-1-5-21-3027362018-461445109-2096225366-1001/a4647d39-e794-4db7-bf79-1f672b0b7e6c/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5459794d44517a4d6a6b344e7a55794d7a49794e7a41344e6a51 Algorithm Group: RSA Algorithm Name: RSA Length: 2048 (0x800) Lengths: dwMinLength = 2048 (0x800) dwMaxLength = 2048 (0x800) dwIncrement = 0 (0x0) dwDefaultLength = 2048 (0x800) UI Policy: dwVersion = 1 (0x1) dwFlags = 0 (0x0) pszCreationTitle = (null) pszFriendlyName = (null) pszDescription = (null) Export Policy: 0 (0x0) (NCRYPT_ALLOW_EXPORT_FLAG -- 1) (NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2) (NCRYPT_ALLOW_ARCHIVING_FLAG -- 4) (NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8) NgcKeyImplType: 2 (0x2) (NCRYPT_IMPL_HARDWARE_FLAG -- 1) NCRYPT_IMPL_SOFTWARE_FLAG -- 2 (NCRYPT_IMPL_REMOVABLE_FLAG -- 8) (NCRYPT_IMPL_HARDWARE_RNG_FLAG -- 10 (16)) Key Usage: 3 (0x3) NCRYPT_ALLOW_DECRYPT_FLAG -- 1 NCRYPT_ALLOW_SIGNING_FLAG -- 2 (NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4) (NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8) (NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)) Private key is NOT exportable

In this example, there is only one passkey registered as we have just activated Windows Hello. In case you had Windows Hello active for a longer time and have registered device-bound passkeys already, the list will be quite extensive.

How to find the right passkey for a specific domain in the Windows 10 certutil export?

The first thing to learn is that Windows Hello actually stores the passkeys under a very long identifier that includes the SHA256 of the relying party ID (domain) where the passkey was created. In our case, we search for the SHA256 representation of "state-of-passkeys.io" (dd52225b9c6….), as you can see below in the table.

How can WebAuthn credentials be distinguished from other entries in the Windows certutil export?

All FIDO2 keys have FIDO_AUTHENTICATOR as part of their identifier.

How to find the right passkey if you have multiple passkeys associated with a specific domain in the Windows 10 certutil export?

If you have registered multiple passkeys for one domain, you need to decode the user.id, which is also part of the identifier. It is encoded as a hex string. In our test, state-of-passkeys.io generated the following unique user.id (dXNyLTYyMDQzMjkyNzUyMzIyNzA4NjQNjQ), which we cannot find directly in the export. However, by decoding the hex string after the SHA256 string, we can identify the passkey that we just generated.

StepContent
IdentifierS-1-5-21-3027362018-461445109-2096225366-1001/ a4647d39-e794-4db7-bf79-1f672b0b7e6c/FIDO_AUTHENTICATOR// dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5459794d44517a4d6a6b344e7a55794d7a49794e7a41344e6a51
SHA256 of rpIDS-1-5-21-3027362018-461445109-2096225366-1001/ a4647d39-e794-4db7-bf79-1f672b0b7e6c/FIDO_AUTHENTICATOR// dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5459794d44517a4d6a6b344e7a55794d7a49794e7a41344e6a51
Explanation:
print(hashlib.sha256("state-of-passkeys.io".encode()).hexdigest()) dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22
user.id as hexcodeS-1-5-21-3027362018-461445109-2096225366-1001/ a4647d39-e794-4db7-bf79-1f672b0b7e6c/FIDO_AUTHENTICATOR// dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5459794d44517a4d6a6b344e7a55794d7a49794e7a41344e6a51
Explanation:
print(bytes.fromhex("64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45").decode()) dXNyLTYyMDQzMjkyNzUyMzIyNzA4NjQNjQ
SHA1 has of public-keyKey Id Hash(sha1): cbd8ad3cc05402afa0bb176708346aea53408832
Public-key in hex octets (with address)Public Key Hex Octets
Actual algorithm used with lengthAlgorithm Group: RSA
Algorithm Name: RSA
Length: 2048 (0x800)
Lengths:
- dwMinLength = 2048 (0x800)
- dwMaxLength = 2048 (0x800)
- dwIncrement = 0 (0x0)
- dwDefaultLength = 2048 (0x800)

The three other important information that can be seen are:

  • SHA1 hash of the public-key: That is the actual SHA1 hash of the public-key.
  • Public-key: The actual public-key is shown in hex octets and prefixed with the offset/address. The data that shown is basically the hex data that is included in a PKCS#1 format. You can see a parsed version here. In another article, we will explain how you can match the public-key from here to the information the browser transfers to the WebAuthn server within credentialPublicKey.
  • Actual algorithm that was used: As Windows 10 does only support RSA as possible encryption algorithm, it is no surprise that this key was created with RS256 which corresponds to ID -257 used in the pubKeyCredParams. More details on how the actual encryption algorithm is chosen can be found in our article WebAuthn pubKeyCredParams & credentialPublicKey: CBOR & COSE

In the next section we will see how this would look like on Windows 10 Parallels VM on a macOS device.

3.2.3 Windows 11 VM (Parallels on ARM-Mac): certutil output#

As we have discussed before, one possible way to test and run Windows is to use a Windows 11 VM on a Mac with Parallels. Within the VM, we will run certutil. Windows 11 has passkey management since the 23H2 update, but certutil still runs as expected. It is interesting to see that the VM can use the secure enclave of the Mac, generating different key types. The algorithm used is ECDSA with a much shorter public key. More information about different algorithms can be found here.

Command:

certutil -csp NGC -key -v

Output:

Microsoft Passport Key Storage Provider: S-1-5-21-2866724682-2111110670-3654107035-1000/4c99708f-4538-4dc8-91ba-9cd4709496b4/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45 ECDSA_P256 RSA Key Id Hash(rfc-sha1): b417bac157f16fd87f72d962c22a5f0cb2a2df05 Key Id Hash(sha1): 495e3b9538dd07f9cee08fdfc4838cd464a6560c Key Id Hash(bcrypt-sha1): c2a19da4ac4b7fd555800bc1b9cdbfc5aa16e382 Key Id Hash(bcrypt-sha256): 3c8955c7fc409bdbef3212a7f4b48dfd6e3e7f7458dde3f765d157357b13f712 Container Public Key: **0000 04 74 e7 0d 43 87 01 ec 9c 7f cd a8 38 49 a2 0f** **0010 83 06 14 e7 e9 0e c4 4d cc a3 42 74 29 46 8f 36** **0020 81 da 5c a5 a7 da fc 89 17 48 71 af 0c 70 70 ec** **0030 7f b5 63 84 49 75 dc 41 64 6e 13 7c 6c 73 f4 f6** **0040 f6** Cached Key Identifier: S-1-5-21-2866724682-2111110670-3654107035-1000/4c99708f-4538-4dc8-91ba-9cd4709496b4/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45: No container name match Cached Key Identifier: S-1-5-21-2866724682-2111110670-3654107035-1000/4c99708f-4538-4dc8-91ba-9cd4709496b4/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45: No KeyId match (NCRYPT_ALLOW_DECRYPT_FLAG -- 1) NCRYPT_ALLOW_SIGNING_FLAG -- 2 (NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4) (NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8) (NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)) UI Policy = 0 (NCRYPT_UI_PROTECT_KEY_FLAG -- 1) (NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG -- 2) Version: 0 Export Policy = 0 (NCRYPT_ALLOW_EXPORT_FLAG -- 1) (NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2) (NCRYPT_ALLOW_ARCHIVING_FLAG -- 4) (NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8) Name: S-1-5-21-2866724682-2111110670-3654107035-1000/4c99708f-4538-4dc8-91ba-9cd4709496b4/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45 Algorithm Group: RSA Algorithm Name: **ECDSA_P256** Length: 2048 (0x800) Lengths: dwMinLength = 2048 (0x800) dwMaxLength = 2048 (0x800) dwIncrement = 0 (0x0) dwDefaultLength = 2048 (0x800) UI Policy: dwVersion = 1 (0x1) dwFlags = 0 (0x0) pszCreationTitle = (null) pszFriendlyName = (null) pszDescription = (null) Export Policy: 0 (0x0) (NCRYPT_ALLOW_EXPORT_FLAG -- 1) (NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG -- 2) (NCRYPT_ALLOW_ARCHIVING_FLAG -- 4) (NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG -- 8) NgcKeyImplType: 1 (0x1) NCRYPT_IMPL_HARDWARE_FLAG -- 1 (NCRYPT_IMPL_SOFTWARE_FLAG -- 2) (NCRYPT_IMPL_REMOVABLE_FLAG -- 8) (NCRYPT_IMPL_HARDWARE_RNG_FLAG -- 10 (16)) Key Usage: 2 (0x2) (NCRYPT_ALLOW_DECRYPT_FLAG -- 1) NCRYPT_ALLOW_SIGNING_FLAG -- 2 (NCRYPT_ALLOW_KEY_AGREEMENT_FLAG -- 4) (NCRYPT_ALLOW_KEY_IMPORT_FLAG -- 8) (NCRYPT_ALLOW_ALL_USAGES -- ffffff (16777215)) Private key is NOT exportable

As in the first example, we have extracted all important information from the command. Keep in mind this key was created with the same rpID and therefore has the same SHA-256 hash, but the user.id is different because a different creation process used a new unique user.id, and a different key-pair was created.

StepContent
IdentifierS-1-5-21-2866724682-2111110670-3654107035-1000/4c99708f-4538-4dc8-91ba-9cd4709496b4/FIDO_AUTHENTICATOR// dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_ 64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45
SHA256 of rpIDS-1-5-21-2866724682-2111110670-3654107035-1000/4c99708f-4538-4dc8-91ba-9cd4709496b4/FIDO_AUTHENTICATOR// dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_ 64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45
Explanation:
print(hashlib.sha256("state-of-passkeys.io".encode()).hexdigest())
dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22
user.id as hexcodeS-1-5-21-2866724682-2111110670-3654107035-1000/4c99708f-4538-4dc8-91ba-9cd4709496b4/FIDO_AUTHENTICATOR// dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_ **64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45
Explanation:
print(bytes.fromhex("64584e794c5467304e7a45774e6a41344d54497a4f4449774e6a45784d6a45").decode())
dXNyLTg0NzEwNjA4MTIzODIwNjExNjExNjExMjE
SHA1 has of public-keyKey Id Hash(sha1): 495e3b9538dd07f9cee08fdfc4838cd464a6560c
Public-key in hex octets (with address)Public Key Hex Octets
Actual algorithm used with lengthAlgorithm Group: RSA
Algorithm Name: ECDSA_P256
Length: 2048 (0x800)
Lengths:
- dwMinLength = 2048 (0x800)
- dwMaxLength = 2048 (0x800)
- dwIncrement = 0 (0x0)
- dwDefaultLength = 2048 (0x800)

From the provided certutil output, we can conclude that the key created in the Windows 11 VM using the secure enclave of the Mac is significantly different from the RSA keys typically generated on a native Windows 10 machine. The primary difference lies in the algorithm used: ECDSA (Elliptic Curve Digital Signature Algorithm) versus RSA ( Rivest–Shamir–Adleman). ECDSA keys, specifically ECDSA_P256, are much shorter in length compared to RSA keys while providing equivalent levels of security.

This is evident from the container public key data, which shows a more compact representation in hex octets. Furthermore, the algorithm name ECDSA_P256 highlights the use of elliptic curve cryptography, which is efficient and well-suited for modern secure environments. In contrast, the native Windows 10 example shows RSA with a key length of 2048 bits, which is larger and less efficient in terms of performance.

4. How to Delete Passkeys on Windows 10?#

In this section, we will look at how to delete passkeys to optimize the authenticator performance. With the accumulation of passkeys over time, Windows Hello may slow down, which can be particularly unproductive for developers. Deleting unnecessary or outdated passkeys can help a faster development experience because the authenticator is loading faster.

4.1 Deleting Passkeys with Command Line Tool certutil#

To delete passkeys using certutil, you need to start a command line with administrative privileges. While listing passkeys can be done without elevated permissions, deleting them requires administrative rights. Here’s how to delete a specific passkey.

certutil -csp NGC -delkey S-1-5-21-3027362018-461445109-2096225366-1001/a4647d39-e794-4db7-bf79-1f672b0b7e6c/FIDO_AUTHENTICATOR//dd52225b9c6e7aafc9d4091b7f97c1b20cbe27644fc1685f65639ede1232aa22_64584e794c5459794d44517a4d6a6b344e7a55794d7a49794e7a41344e6a51

Explanation:

  • certutil: Command-line utility provided by Windows for certificate management tasks.

  • -csp NGC: This specifies the Cryptographic Service Provider (CSP) to be used. NGC stands for Next Generation Credentials.

  • -delkey: This option is used to delete the specified key.

  • <Identifier>: The identifier of the passkey to be deleted. It includes the user SID, a unique identifier for the passkey, and the SHA256 of the rpID and the hex string user.id (as explained above).

Using this approach, you can delete the passkeys after selecting the appropriate identifiers manually, which is quite tiring.

4.2 Deleting Passkeys with webauthn-fido2-key-remover#

In the following section, we will use the webauthn-fido2-key-remover and introduce some smaller tweaks into the source-code.

4.2.1 Using the Latest Release from webauthn-fido2-key-remover Directly#

The original version of webauthn-fido2-key-remover was created in 2021 (long before passkeys appeared). It internally issues the same commands that we have outlined above but with a CLI. It decodes the user.id and shows the SHA256 hash of the rpID. When started with administrative privileges, you can also delete passkeys. Here is a short animation that shows the functionality (taken from the official README):

WebAuthn Fido2 Key Remover

When we were using the CLI tool, we still had the difficulties that we would have to lookup the SHA256 hashes (as only a short list of rpIDs where incorporated into the tool).

4.2.2 Using Latest webauthn-fido2-key-remover Version from Corbado#

We have forked and created a pull request with our modifications for the webauthn-fido2-key-remover (has not been merged yet). You can find our version here: https://github.com/kopy/webauthn-fido2-key-remover. The following adjustments have been made:

  • Adding default rpIDs: We have included common WebAuthn & passkey playgrounds (mainly used by developers during implementation & testing) and also added larger popular platforms like google.com, github.com, and microsoft.com to allow for easier deletion of test accounts here.

  • CSV lookup functionality for rpIDs: We added functionality to look up rpIDs from custom domain names in a text/CSV list, enabling further distinction of passkeys from your own environment. The CSV file needs to be in the same path as the executable and needs to be named domains.csv.

  • Minor adjustments: We updated the versions and made some smaller library adjustments necessary due to library version changes.

We plan to release further simplifications, such as a ruleset that automatically deletes test accounts based on their naming.

5. Recommendation#

When testing or working with Windows 10 as a developer in the field of passkeys, there are limited ways to test implementation. However, it is crucial to know how to navigate the Windows Hello authenticator (as the main authenticator for desktop).

  • Use our adjusted version of webauthn-fido2-key-remover: We recommend running or compiling our version with the custom domain list. This will facilitate the cleanup of unnecessary passkeys and streamline the process of deleting test accounts. You can find our version here: https://github.com/kopy/webauthn-fido2-key-remover.

  • Easiest way to delete all passkeys: The simplest method to delete all passkeys is to remove the Windows Hello PIN and then re-add it. This action effectively removes all stored passkeys, providing a clean start but keep in mind this might lock you out of some real accounts.

  • Create a separate Windows user profile: Consider creating a separate Windows user profile specifically for testing purposes. This allows for easier resetting and deleting of all passkeys. Additionally, it is important to test scenarios with a deactivated authenticator to ensure comprehensive coverage.

To ensure a smooth development experience, it is essential to manage passkeys efficiently. By following the outlined steps and using the recommended tools, you can maintain optimal authenticator performance and streamline your workflow.

6. Conclusion#

Managing and deleting passkeys on Windows 10 is essential for maintaining optimal system performance, especially for developers working with passkey-first authentication solutions. We addressed and answered our initial questions:

  • Understand Windows 10 WebAuthn cryptography: Passkeys and WebAuthn credentials are securely stored in locations such as LSA Secrets and the Credential Store. Credential creation involves generating key pairs, with private keys stored securely on the device and public keys sent to the authenticating server. Security measures include encryption, access controls, and attestation to protect user credentials.

  • Learn how to manage and remove passkeys on Windows 10: Use the certutil command-line tool to list, analyze, and delete passkeys. Activate Windows Hello to enable passkey functionality. Utilize the webauthn-fido2-key-remover tool for more comfortable passkey management.

By following these steps and recommendations, you can effectively manage and delete passkeys on Windows 10, optimizing the performance of the Windows Hello authenticator and enhancing your overall development experience. This all helps developers in building secure applications to make the Internet a safer place.

Share this article


LinkedInTwitterFacebook

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free