I would like to create an AES key encrypted by the TPM on Windows, using PowerShell. The code below successfully creates a self-signed certificate with the TPM and for testing purposes encrypts a short string with the public key. But then I can't decrypt using the private key. I do understand that the key is not exportable, but I was thinking that the TPM should be able to decrypt, I just don't know how to do that with PowerShell.
The code tries to access the private key but fails with: Error retrieving property '$PrivateKey': $Exception getting "PrivateKey": "Invalid provider type specified."
Is there something wrong with the certificate creation? I have tried -KeySpec KeyExchange according to "Invalid provider type specified" CryptographicException when trying to load private key of certificate, but the PrivateKey property is still inaccessible with the same error.
Or is there some other PowerShell code to use in this case for decryption through the TPM?
Or should I in some way create the AES key directly with the TPM, and in that case, how would that be done with PowerShell?
$params = @{
Type = 'Custom'
Provider = 'Microsoft Platform Crypto Provider'
Subject = 'CN=Patti Fuller'
TextExtension = @(
'2.5.29.37={text}1.3.6.1.5.5.7.3.2',
'2.5.29.17={text}[email protected]' )
KeyExportPolicy = 'NonExportable'
KeySpec = 'KeyExchange'
KeyUsage = @('DataEncipherment','DigitalSignature','KeyAgreement','KeyEncipherment')
KeyAlgorithm = 'RSA'
KeyLength = 2048
CertStoreLocation = 'Cert:\CurrentUser\My'
}
$cert = New-SelfSignedCertificate @params
# Encrypt test string using the public key
$bytesToEncrypt = [System.Text.Encoding]::UTF8.GetBytes("Hello") # For simplicity, I use a simple string instead of AES key
$encryptedBytes = $cert.PublicKey.Key.Encrypt($bytesToEncrypt, $true)
# Attempt decrypt the content using the private key
$privateKey = $cert.PrivateKey
# Error retrieving property '$PrivateKey': $Exception getting "PrivateKey": "Invalid provider type specified."
Write-Output "Private key: $privateKey"
if ($privateKey -ne $null) {
$decryptedBytes = $privateKey.Decrypt($encryptedBytes, $true)
$decryptedContent = [System.Text.Encoding]::UTF8.GetString($decryptedBytes)
Write-Output "Decrypted content: $decryptedContent"
}