Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract private key from pfx file or certificate store WITHOUT using OpenSSL on Windows

As the title suggests I would like to export my private key without using OpenSSL or any other third party tool. If I need a .cer file or .pfx file I can easily export these via MMC or PowerShell pkiclient but I can't find a way to get the private key.

https://learn.microsoft.com/en-us/powershell/module/pkiclient/export-certificate?view=win10-ps

Using an online tool like https://www.sslshopper.com/ssl-converter.html is not OK.

PSVersion:

PS C:\Users\oscar> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.17134.228
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17134.228
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

I can get the public key like this:

(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetPublicKey()

And export the entire certificate like this:

(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetRawCertData()

Result from

PS C:\Users\oscar> $mypwd = ConvertTo-SecureString -String "MyPassword" -Force -AsPlainText
PS C:\Users\oscar> $mypfx = Get-PfxData -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $mypwd
PS C:\Users\oscar> $mypfx

OtherCertificates EndEntityCertificates
----------------- ---------------------
{}                {[Subject]...


PS C:\Users\oscar> $mypfx.EndEntityCertificates

Thumbprint                                Subject
----------                                -------
8ED4971564E35099D6DB490C3756E2AD43AAAAAA  CN=localhost

Tested the command from @Brad but I got the error below.

Private key is NOT plain text exportable

certutil -exportPFX -p "myPassword" -privatekey -user my <Certificate Serial Number> C:\localhost.pfx

enter image description here

Similar to Certificate Export Wizard in MMC certificates, only export to .pfx available if the key is included.

enter image description here

like image 599
Ogglas Avatar asked Oct 22 '18 12:10

Ogglas


People also ask

Can you extract private key from certificate?

Go to: Certificates > Personal > Certificates. Right-click on the certificate you wish to export and go to All Tasks and hit Export. Hit Next on the Certificate Export Wizard to begin the process. Select “Yes, export the private key” and hit next.


3 Answers

I had the same problem and solved it with the help of PSPKI Powershell module from PS Gallery. While I understand that you look for a solution that preferably uses some built in functionality in Windows, installing a module from PS Gallery might be acceptable. At least it was in my case.

First install the PSPKI module (I assume hat the PSGallery repository has already been set up):

Install-Module -Name PSPKI

The PSPKI module provides a Cmdlet Convert-PfxToPem which converts a pfx-file to a pem-file which contains the certificate and pirvate key as base64-encoded text:

Convert-PfxToPem -InputFile C:\path\to\pfx\file.pfx -Outputfile C:\path\to\pem\file.pem

Now, all we need to do is splitting the pem-file with some regex magic. For example, like this:

(Get-Content C:\path\to\pem\file.pem -Raw) -match "(?ms)(\s*((?<privatekey>-----BEGIN PRIVATE KEY-----.*?-
----END PRIVATE KEY-----)|(?<certificate>-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----))\s*){2}"

$Matches["privatekey"] | Set-Content "C:\path\to\key\file.pem"
$Matches["certificate"] | Set-Content "C:\path\to\certificate\file.pem"
like image 115
Christoph Böhme Avatar answered Oct 08 '22 21:10

Christoph Böhme


Based on what PowerShellGuy mentioned.

Will that work for you?

# first get your cert, either via pure .NET, or through the PSDrive (Cert:\)

# this is just an example

# get cert from PSDrive
$cert = Get-ChildItem Cert:\LocalMachine\My | where Subject -eq 'CN=MySubject'

# get cert from .NET
$My     = [System.Security.Cryptography.X509Certificates.StoreName]::My
$Store  = [System.Security.Cryptography.X509Certificates.X509Store]::new($My,'localmachine')
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::MaxAllowed)

$cert   = $Store.Certificates | where Subject -eq 'CN=MySubject'

# get private key
# PKCS8, way #1
$BytesPkcs8 = $cert.PrivateKey.ExportPkcs8PrivateKey()
[System.Convert]::ToBase64String($BytesPkcs8)

# PKCS8, way #2
$Pkcs = [System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob
$BytesPkcs8 = $cert.PrivateKey.Key.Export($Pkcs)
[System.Convert]::ToBase64String($BytesPkcs8)

# RSA
$BytesRsa = $cert.PrivateKey.ExportRSAPrivateKey()
[System.Convert]::ToBase64String($BytesRsa)

So is that Base64 string what you're looking for?

like image 20
Panos.G Avatar answered Oct 08 '22 19:10

Panos.G


Try this script which exports the private key in Pkcs8 format

Azure PowerShell - Extract PEM from SSL certificate

like image 1
RashadRivera Avatar answered Oct 08 '22 20:10

RashadRivera