Extract private key from pfx file or certificate store WITHOUT using OpenSSL on Windows
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"
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?
If I understand correctly certutil should do it for you.
certutil -exportPFX -p "ThePasswordToKeyonPFXFile" my [serialNumberOfCert] [fileNameOfPFx]