Recovering a certificate where the private key is marked as non-exportable

When importing a certificate and private key in Windows (e.g. from a PFX file), you are given the option to mark the key as exportable. If this is not ticked, it is not possible to export the private key at a later date.

The below instructions provide a method of extracting the private key into a PFX file.

On the server with the private key

Follow the below instructions. A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 is the thumbprint of the certificate.

From a PowerShell prompt, run the following commands to identify the file where the private key is stored:

PS C:\Windows\system32> $a = Get-Item Cert:\LocalMachine\My\A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0
PS C:\Windows\system32> $a.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName

50ed65430216d17c6e6efff6819c923b_92a9b8e0-fce8-4402-8b90-66196ad1d0d1

From an elevated command prompt use PsExec to spawn a command prompt in the SYSTEM context and extract the private key data.

C:> PsExec64.exe -s -i cmd
C:> copy "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys\50ed65430216d17c6e6efff6819c923b_92a9b8e0-fce8-4402-8b90-66196ad1d0d1" c:\

On a non-production computer

On a non-production computer import the public certificate part (.cer/.crt). Copy the file from above to C:\ .

From a PowerShell prompt, find the GUID that represents this computer.

PS C:\Windows\system32> Get-ItemPropertyValue Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\ -Name MachineGuid

2801936f-1239-4daa-89e5-f78df0ae0f2a

Rename the file you placed in C:\ so that the value after the underscore (_) matches the MachineGuid value. In our example, the file will now be named
50ed65430216d17c6e6efff6819c923b_2801936f-1239-4daa-89e5-f78df0ae0f2a

From a PowerShell prompt, move the file to the certificate store on this machine

PS C:\Windows\system32> Move-Item "C:\50ed65430216d17c6e6efff6819c923b_92a9b8e0-fce8-4402-8b90-66196ad1d0d1" "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys\50ed65430216d17c6e6efff6819c923b_2801936f-1239-4daa-89e5-f78df0ae0f2a"

From an elevated cmd prompt, run:

 C:> certutil -repairstore my AA73A8D8B69122DB7A861257400E52E4C14E39E5

If you now check the local machine certificate store you will notice a padlock icon against the certificate, indicating the private key is available. You can now export the certificate with the private key.

Published by

Dave Hope

Dave is a Principal Software Analyst for a UK based retirement developer, in his spare time he enjoys digital photography and rock climbing.

7 thoughts on “Recovering a certificate where the private key is marked as non-exportable”

  1. I tried this, but `$a.PrivateKey` is null for keys marked as non-exportable (it works if they are *not* marked like this).

    I checked with `certutil -store my A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 instead, which provides the container name – but there is no file on disk with the same name.

    Am I doing something wrong here?

    1. So I found the key, but in `C:\Users\All Users\Microsoft\Crypto\Keys` instead of `C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys`.

      After copying this to a non-prod machine and running certutil, I get:

      “`
      Cannot find the certificate and private key for decryption.
      CertUtil: -repairstore command FAILED: 0x80090010 (-2146893808 NTE_PERM)
      CertUtil: Access denied.
      “`

  2. Dave,
    Your post would be really helpful if I could follow it. having trouble with the very first line. When using PS, I can use the $a = Get-Item and them PS prompts me for input. I pop in the Cert:\LocalMachine\My\A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0 but that’s where it falls apart. I can’t get it to return a value.

  3. Hi Dave,

    thx for the method, but I could not make it to work 🙁 On Windows 2016. The thing failed on certutil step saying that the encryption does not match or something

  4. Hello, thanks for the article, however, I cannot perform the last step

    `certutil -repairstore my AA73A8D8B69122DB7A861257400E52E4C14E39E5`

    I assume it is a thumbprint of a certificate?

    I get the error:

    certutil -repairstore my 156A44C4E11DFBACDDFB400700F264D9DFB1258F my “Personal”
    CertUtil: -repairstore command FAILED: 0x80090011 (-2146893807 NTE_NOT_FOUND)
    CertUtil: Object was not found.

    And the file in folder has type `File`, whereas other files have type `System File`.

    1. Ouch, I missed a step with importing a certificate.
      After I did it, I get the following error:

      certutil -repairstore my 156A44C4E11DFBACDDFB400700F264D9DFB1258F
      my “Personal”
      ================ Certificate 1 ================
      Serial Number: …
      Issuer: E=…
      NotBefore: 26-9-2017 15:05
      NotAfter: 25-9-2022 15:05

      Signature matches Public Key
      Root Certificate: Subject matches Issuer
      Cert Hash(sha1): …
      No key provider information
      Cannot find the certificate and private key for decryption.
      CertUtil: -repairstore command FAILED: 0x8009000b (-2146893813 NTE_BAD_KEY_STATE)
      CertUtil: Key not valid for use in specified state.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.