by: Helge, published: Jun 30, 2021, in

Checking Windows Hello Key Storage: TPM or Software?

Windows Hello for Business (WHfB) stores a cryptographic key on the device. The preferred storage location is a hardware TPM module. However, if a TPM is not available, the key may be stored in the filesystem instead. It’s surprisingly hard to determine the storage location for existing Windows Hello for Business keys. This article presents a simple solution.

Windows Hello Key Storage Provider

Windows Hello for Business keys are managed by the Microsoft Passport Key Storage Provider.

Listing a Provider’s Keys With Certutil

The certutil command-line tool has the capability to list the keys for a given provider. The Microsoft Passport Key Storage Provider keys can be retrieved with the following command (must be run as the user whose keys you’re interested in):

C:\>certutil -csp "Microsoft Passport Key Storage Provider" -key

With a Microsoft account, the output looks like this:

Microsoft Passport Key Storage Provider:

With an Azure Active Directory (AAD) account, the output format is a little different:

Microsoft Passport Key Storage Provider:

Please note that I replaced my keys’ identifiers with the placeholders USER-SID, GUID, SOME-ID, AAD-TENANT-ID, and USER-PRINCIPAL-NAME.

NgcKeyImplType: Hardware (TPM) or Software?

In order to determine a key’s storage location, we add the -v parameter to the certutil command:

C:\>certutil -csp "Microsoft Passport Key Storage Provider" -key -v

Let’s examine the NgcKeyImplType section of the output. A key stored in a hardware trusted platform module (TPM) generates the following:

NgcKeyImplType: 1 (0x1)

The weird formatting does not make it immediately obvious, but in the above output, the value is NCRYPT_IMPL_HARDWARE_FLAG (1).

A key stored by a software provider on disk generates the slightly different output:

NgcKeyImplType: 2 (0x2)

In this case, the value is NCRYPT_IMPL_SOFTWARE_FLAG (2).

The four possible values for NgcKeyImplType are documented as follows:

  • NCRYPT_IMPL_HARDWARE_FLAG: the provider is hardware based.
  • NCRYPT_IMPL_SOFTWARE_FLAG: the provider is software based.
  • NCRYPT_IMPL_REMOVABLE_FLAG: the provider is removable.
  • NCRYPT_IMPL_HARDWARE_RNG_FLAG: the provider is a hardware based random number generator.

This answers the question asked in the title. The remainder of this article sheds light on additional details such as key migration from software to hardware storage.

Finding a Key’s Certificate

To find the certificate a key belongs to, we can run the following command (again, as the user, Hello puts certificates in the Personal store):

C:\>certutil -user -store My

In the case of an Azure Active Directory user account, the certificate’s Issuer, Subject, and Key Container properties are identical to the key name as shown above. Sample output:

================ Certificate 2 ================
Serial Number: 12345678901234567890123456789012
 NotBefore: 11.10.2019 21:50
 NotAfter: 11.10.2049 22:00
Signature matches Public Key
Root Certificate: Subject matches Issuer
Cert Hash(sha1): 1234567890123456789012345678901234567890
  Key Container = USER-SID/GUID/
  Provider = Microsoft Passport Key Storage Provider
Private key is NOT exportable
Encryption test passed

The certificate’s intended purpose is Smart Card Logon.

Migrating From Software Key Storage to TPM

The verbose certutil output we generated above shows that Windows Hello for Business keys are not exportable:

Export Policy: 0 (0x0)

This means there is no migration path from a software key to a key stored in a TPM. Instead, existing WHfB data needs to be deleted, followed by a re-enrollment. I’m aware of two way to delete Windows Hello for Business data.

Deleting the Hello Container With Certutil

To delete the Windows Hello for Business data container run the following command (yes, the user needs to be logged off afterwards):

certutil -DeleteHelloContainer

Reset Hello by Deleting the Database on Disk

Alternatively, stop the Windows Biometric service, delete its database on disk and start it again:

net stop WbioSrvc
del /f /q C:\Windows\System32\WinBioDatabase\*.*
net start WbioSrvc

Note: it might be a good idea to move the files to a safe place instead, just in case.

Further Reading

Some interesting articles with additional details:

Previous Article How to Check the TPM Status & Enable the CPU's fTPM/PTT
Next Article Finding (Executables in) User-Writeable Directories