Search code examples
powershellcertificate

Retrieve KeySpec Value from Certificate Using PowerShell


I am attempting to verify a certificate in the machine store has KeySpec set to AT_KEYEXCHANGE. Using certutil.exe does provide this information, but requires string parsing. I would prefer to avoid string parsing to avoid assumptions on the output of certutil.exe that I do not know will always be true across different versions of Windows.

I have looked at the properties and methods for System.Security.Cryptography.X509Certificates.X509Certificate2 and System.Security.Cryptography.X509Certificates.RSACertificateExtensions.

How can I retrieve the KeySpec from the certificate in the certificate store?


Solution

  • I was able to find the KeySpec with the help from here and here. The CspKeyContainerInfo class contains a property called KeyNumber, which is what certutil refers to as KeySpec.

    There are two methods I have found. One that works for only PowerShell 5 and the other that works for both PowerShell 5 and 7.

    PowerShell 5 Only

    $Cert = (Get-ChildItem -Path Cert:\LocalMachine\My)[1]
    $Cert.PrivateKey.CspKeyContainerInfo.KeyNumber
    

    PowerShell 5 and 7

    $Cert = (Get-ChildItem -Path Cert:\LocalMachine\My)[1]
    $PrivateKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($Cert)
    $CngProvider = [System.Security.Cryptography.CngProvider]::new($PrivateKey.Key.Provider)
    $CngKey = [System.Security.Cryptography.CngKey]::Open($PrivateKey.Key.KeyName,  $CngProvider, [System.Security.Cryptography.CngKeyOpenOptions]::MachineKey)
    $CspParameters = [System.Security.Cryptography.CspParameters]::New(1, $CngKey.Provider, $CngKey.KeyName)
    $CspParameters.Flags = [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore
    $CspKeyContainerInfo = [System.Security.Cryptography.CspKeyContainerInfo]::New($CspParameters)
    $CspKeyContainerInfo.KeyNumber