Generate and manage TPM-protected keys in Windows using PowerShell
Storing private keys in a Trusted Platform Module (TPM) is a secure and reliable way to protect cryptographic operations on a Windows 11 device.
This tutorial walks you through how to use TPM-backed key storage using PowerShell, with a focus on the Microsoft Platform Crypto Provider (PCP).
Why use TPM for key storage?
A TPM helps ensure that private keys are protected from theft or tampering. Once stored in the TPM, keys become non-exportable, and all operations using them must go through secure hardware-based access.
Windows provides two ways to interact with TPM hardware:
Each serves different needs depending on how deeply you want to work with TPM features.
PCP versus TBS: What's the Difference?
Feature | Platform Crypto Provider (PCP) | TPM Base Services (TBS) |
---|---|---|
Abstraction level | High-level API | Low-level TPM access |
Primary use case | Key storage and cryptographic operations | Direct TPM command execution |
Developer complexity | Easier to implement, less TPM-specific knowledge | Requires understanding of TPM commands |
Integration | Tightly integrated with Windows features | Suited for custom security solutions |
Microsoft Platform Crypto Provider (PCP)
PCP is typically used in scenarios where applications require secure key storage and cryptographic operations without the need for direct TPM command management. Key features include:
Key protection: Creates and stores cryptographic keys inside the TPM, ensuring private keys are non-exportable and protected from unauthorized access.
Integration with Windows Security Features: Integrates with Windows security features like BitLocker and Windows Hello for Business, enhancing security by leveraging TPM-backed keys.
Simplified API: Offers simplified APIs for secure key storage and cryptographic operations.
TPM Base Services (TBS)
TBS is a low-level system service that provides a standardized interface for applications to communicate directly with the TPM. TBS is suited for scenarios where applications require direct interaction with the TPM, such as custom security solutions or specialized hardware integrations. Its primary functions include:
Direct TPM command execution: Provides raw access to TPM command sets, offering granular control over TPM functionalities.
Resource management: Manages multiple app access to TPM resources, ensuring that TPM resources are used efficiently and without conflicts.
Support for custom TPM operations: Enables advanced or vendor-specific TPM functionality
Use PCP and PowerShell to generate a TPM-backed key and CSR
This example shows how to generate a TPM-backed key and create a certificate signing request (CSR) using PowerShell and PCP.
Before you begin
Install Windows 11 with a TPM2
Install PowerShell (should run as Administrator)
Open PowerShell as an Administrator.
Ensure a TPM is present by running the following PowerShell command:
Get-Tpm
Your output will resemble the example below:
TpmPresent : True TpmReady : True …
Run the following PowerShell script:
# Define key container and subject info $keyName = "TPMKey" $subject = "CN=My TPM CSR" # 1. Create a TPM-backed key pair using CNG Write-Host "Creating TPM-backed key..." $provider = "Microsoft Platform Crypto Provider" $key = New-Object System.Security.Cryptography.CngKeyCreationParameters $key.Provider = $provider $key.KeyCreationOptions = [System.Security.Cryptography.CngKeyCreationOptions]::OverwriteExistingKey $key.ExportPolicy = [System.Security.Cryptography.CngExportPolicies]::None $key.KeyUsage = [System.Security.Cryptography.CngKeyUsages]::Signing [System.Security.Cryptography.CngKey]::Create("RSA", $keyName, $key) Write-Host "TPM key created with name: $keyName" # 2. Create an INF file for CSR generation $infPath = "$env:TEMP\csr.inf" $csrPath = "$env:TEMP\csr.req" $infContent = @" [Version] Signature="$Windows NT$" [NewRequest] Subject = "$subject" KeySpec = 1 KeyLength = 2048 Exportable = FALSE MachineKeySet = TRUE ProviderName = "$provider" KeyContainer = "$keyName" HashAlgorithm = sha256 RequestType = PKCS10 [Extensions] 2.5.29.17 = "{text}" _continue_ = "dns=example.com&" _continue_ = "dns=www.example.com" [RequestAttributes] CertificateTemplate = User "@ Set-Content -Path $infPath -Value $infContent -Encoding ASCII # 3. Generate the CSR Write-Host "Generating CSR..." certreq.exe -new $infPath $csrPath if (Test-Path $csrPath) { Write-Host "CSR successfully created at: $csrPath" Get-Content $csrPath } else { Write-Error "CSR generation failed." } # Cleanup temporary files (optional) # Remove-Item $infPath
Submit the CSR to a certificate authority.
Submit the generated CSR (
csr.req
) to DigiCert® Device Trust Manager over any of the Certificate management methods, such as REST, EST, SCEP, CMPv2 or ACME to obtain a signed certificate. See:Install the issued certificate.
Once you receive the signed certificate (for example,
tpm_certificate.cer
), install it by running the following command:certreq -accept tpm_certificate.cer
This command associates the certificate with the existing TPM-protected private key.
Cleanup
To delete the TPM-backed key created with the Microsoft Platform Crypto Provider in Windows (for example, named TPMKey), you can use the PowerShell and the Windows CNG APIs.
Run the following PowerShell command:
$keyName = "TPMKey" $provider = "Microsoft Platform Crypto Provider" # Attempt to open and delete the key try { $key = [System.Security.Cryptography.CngKey]::Open($keyName, $provider) $key.Delete() Write-Host "Key '$keyName' successfully deleted from TPM." } catch { Write-Warning "Failed to delete key '$keyName'. It may not exist or is not accessible." }
If you used the key to enroll a certificate, you might want to remove that certificate as well:
# Remove certs that reference the TPM key by container name Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.PrivateKey.CspKeyContainerInfo.KeyContainerName -eq "TPMKey" } | Remove-Item
See How Windows uses the Trusted Platform Module for information.