How to export non-exportable private key from store
I need to export private key from Windows store. What should I do if the key is marked as non-exportable? I know that it is possible, program jailbreak can export this key.
To export key I use Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair()
that exports key from (RSACryptoServiceProvider)cryptoProv.ExportParameters(true)
. Exported key I use in Org.BouncyCastle.Cms.CmsSignedDataGenerator
for CMS signature.
I need solution for .Net, but any solution will be useful. Thank you.
Solution 1:
You're right, no API at all that I'm aware to export PrivateKey marked as non-exportable. But if you patch (in memory) normal APIs, you can use the normal way to export :)
There is a new version of mimikatz that also support CNG Export (Windows Vista / 7 / 2008 ...)
- download (and launch with administrative privileges) : http://blog.gentilkiwi.com/mimikatz (trunk version or last version)
Run it and enter the following commands in its prompt:
-
privilege::debug
(unless you already have it or target only CryptoApi) -
crypto::patchcng
(nt 6) and/orcrypto::patchcapi
(nt 5 & 6) -
crypto::exportCertificates
and/orcrypto::exportCertificates CERT_SYSTEM_STORE_LOCAL_MACHINE
The exported .pfx files are password protected with the password "mimikatz"
Solution 2:
Gentil Kiwi's answer is correct. He developed this mimikatz tool that is able to retrieve non-exportable private keys.
However, his instructions are outdated. You need:
Download the lastest release from https://github.com/gentilkiwi/mimikatz/releases
Run the cmd with admin rights in the same machine where the certificate was requested
Change to the mimikatz bin directory (Win32 or x64 version)
Run
mimikatz
Follow the wiki instructions and the .pfx file (protected with password mimikatz) will be placed in the same folder of the mimikatz bin
mimikatz # crypto::capi
Local CryptoAPI patchedmimikatz # privilege::debug
Privilege '20' OKmimikatz # crypto::cng
"KeyIso" service patchedmimikatz # crypto::certificates /systemstore:local_machine /store:my /export
* System Store : 'local_machine' (0x00020000)
* Store : 'my'
- example.domain.local
Key Container : example.domain.local
Provider : Microsoft Software Key Storage Provider
Type : CNG Key (0xffffffff)
Exportable key : NO
Key size : 2048
Public export : OK - 'local_machine_my_0_example.domain.local.der'
Private export : OK - 'local_machine_my_0_example.domain.local.pfx'
Solution 3:
I wanted to mention Jailbreak specifically (GitHub):
Jailbreak
Jailbreak is a tool for exporting certificates marked as non-exportable from the Windows certificate store. This can help when you need to extract certificates for backup or testing. You must have full access to the private key on the filesystem in order for jailbreak to work.
Prerequisites: Win32
-
Download the executable binaries for your version of Windows (e.g. jailbreak64.exe).
-
Start an elevated command prompt.
-
Run the command
jailbreak64.exe %WINDIR%\system32\mmc.exe %WINDIR%\system32\certlm.msc -64
(note - this is not quite the same as the guidance on github.certlm.msc
is used on Windows 2016 and 2019 to bring up the local machine certificate store).
Solution 4:
There is code and binaries available here for a console app that can export private keys marked as non-exportable, and it won't trigger antivirus apps like mimikatz will.
The code is based on a paper by the NCC Group.
will need to run the tool with the local system account, as it works by writing directly to memory used by Windows' lsass
process, in order to temporarily mark keys as exportable. This can be done using PsExec
from SysInternals' PsTools:
-
Spawn a new command prompt running as the local system user:
PsExec64.exe -s -i cmd
-
In the new command prompt, run the tool:
exportrsa.exe
-
It will loop over every Local Computer store, searching for certificates with a private key. For each one, it will prompt you for a password - this is the password you want to secure the exported PFX file with, so can be whatever you want