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 works in IT for a leading UK based retirement developer, in his spare time he enjoys tinkering with technology and rock climbing.

12 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.

  5. Hi Dave, your last lines are

    From an elevated cmd prompt, run:
    C:> certutil -repairstore my AA73A8D8B69122DB7A861257400E52E4C14E39E5

    Where this ‘AA73A8D8B69122DB7A…’ came from ?

    Thanks in advance
    🙂

  6. If you are seeing the key in: `C:\Users\All Users\Microsoft\Crypto\Keys` instead of `C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys` this may be because you are trying to get the root CA certificate from a Microsoft Windows Certificate Authority, rather than just a key of a web server cert for example.

  7. Hi Dave, everything worked as you instructed except the file copy as system, It reported it could not find the file. I browsed to the same local in file explorer (as admin) with system files displayed and was able to see and copy the file.
    I exported the existing certificate with the non exportable private key as a DER cer file
    Copied the exported certificate and the copied file to another server, found the machine GUID from the new server and renamed the suffix on the file. Copied it into the same location on the new server and used the certificate mmc plug in to imported the certificate into the personal folder of the local machine store along with the intermediate certificates. I then ran the certutil command and it is unable to repair:-
    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.

    Any suggestions?

  8. Great article! Just you missed where the “AA73A8D8B69122DB7A861257400E52E4C14E39E5” comes from.

    ANSWER:
    After importing the certificate, you need to run:
    certutil.exe -store my
    You’ll get a list of your certificates. Locate the imported certificate and take note of its “Cert Hash(sha1)” number.
    That number will be used for “certutil -repairstore my”.

Leave a Reply to James Cancel 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.