在Windows上不使用OpenSSL从pfx文件或证书存储中提取私钥
正如标题所示,我希望在不使用OpenSSL或任何其他第三方工具的情况下导出私钥。如果我需要在Windows上不使用OpenSSL从pfx文件或证书存储中提取私钥,windows,powershell,certificate,certificate-store,Windows,Powershell,Certificate,Certificate Store,正如标题所示,我希望在不使用OpenSSL或任何其他第三方工具的情况下导出私钥。如果我需要.cer文件或.pfx文件,我可以通过MMC或PowerShellpkiclient轻松导出这些文件,但我找不到获取私钥的方法 使用像这样的在线工具是不合适的 PSV: PS C:\Users\oscar> $PSVersionTable Name Value ---- ----- PSVers
.cer
文件或.pfx
文件,我可以通过MMC或PowerShellpkiclient
轻松导出这些文件,但我找不到获取私钥的方法
使用像这样的在线工具是不合适的
PSV:
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
我可以像这样获取公钥:
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetPublicKey()
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetRawCertData()
$mypwd = ConvertTo-SecureString -String "MyPassword" -Force -AsPlainText
$mypfx = Get-PfxData -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $mypwd
Export-PfxCertificate -PFXData $mypfx -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $NewPwd
(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"
并按如下方式导出整个证书:
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetPublicKey()
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetRawCertData()
$mypwd = ConvertTo-SecureString -String "MyPassword" -Force -AsPlainText
$mypfx = Get-PfxData -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $mypwd
Export-PfxCertificate -PFXData $mypfx -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $NewPwd
(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"
因
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
测试了@Brad的命令,但我得到了下面的错误
私钥不可纯文本导出
certutil-exportPFX-p“我的密码”-privatekey-user my C:\localhost.pfx
与MMC证书中的证书导出向导类似,仅当包含密钥时,才能导出到.pfx
如果我理解正确,certutil应该为您做这件事
certutil-exportPFX-p“thepasswordtoyonpfxfile”我的[serialNumberOfCert][filenameoffx]
当密钥可导出时,可以使用多个API将其导出为多种格式。最常见的是PKCS#8(行业标准)和XML(MSFT Property afaik)
看看这些答案:
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetPublicKey()
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetRawCertData()
$mypwd = ConvertTo-SecureString -String "MyPassword" -Force -AsPlainText
$mypfx = Get-PfxData -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $mypwd
Export-PfxCertificate -PFXData $mypfx -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $NewPwd
(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"
嗯,你有没有试过打开证书商店,然后通过这种方式获取私钥?但可以肯定的是,这只适用于RSA/DSA证书
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::My,"localmachine")
$store.Open("MaxAllowed")
$cert = $store.Certificates | ?{$_.subject -match "^CN=asdasd"}
$cert.PrivateKey.ToXmlString($false)
$store.Close()
我也遇到了同样的问题,在PS Gallery的帮助下解决了它。虽然我知道您正在寻找一种解决方案,该解决方案最好使用Windows中的一些内置功能,但从PS Gallery安装模块可能是可以接受的。至少对我来说是这样 首先安装PSPKI模块(我假设已经设置了PSGallery存储库): PSPKI模块提供了一个Cmdlet
Convert-PfxToPem
,该Cmdlet将pfx文件转换为pem文件,其中包含证书和pirvate密钥作为base64编码文本:
Convert-PfxToPem -InputFile C:\path\to\pfx\file.pfx -Outputfile C:\path\to\pem\file.pem
现在,我们所需要做的就是用一些正则表达式魔法拆分pem文件。例如,像这样:
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetPublicKey()
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetRawCertData()
$mypwd = ConvertTo-SecureString -String "MyPassword" -Force -AsPlainText
$mypfx = Get-PfxData -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $mypwd
Export-PfxCertificate -PFXData $mypfx -FilePath C:\Users\oscar\Desktop\localhost.pfx -Password $NewPwd
(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"
(获取内容C:\path\to\pem\file.pem-Raw)-match“(?ms)(\s*(?----开始私钥------.*-
----结束私钥----------------(?----开始证书------.*.----结束证书------))\s*){2}”
$Matches[“privatekey”]|将内容设置为“C:\path\to\key\file.pem”
$Matches[“certificate”]|将内容设置为“C:\path\to\certificate\file.pem”
基于PowerShellGuy提到的内容
那对你有用吗
# 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)
那么,您正在寻找的是Base64字符串吗?您确实需要一个
.pfx
文件,因为.cer
文件不存储私钥。您的$pVersionTable
是什么?您可以使用Get PfxData-FilePath'mycertificate.pfx'-Password(ConvertTo SecureString-Force-AsPlainText-String'MyClearTextPassword')
?@PetruZaharia是的,我知道,这是一个您可以导出的示例。:)用PSVersion和我的尝试更新了问题。我可以,但我没有找到导出私钥的方法。导出PfxCertificate
-“将证书或PFXData对象导出到个人信息交换(PFX)文件。”我只想要私钥。看起来不错,但即使助手说导出证书和私钥
,我还是收到了消息私钥不是纯文本可导出的
。我只能导出到.pfx
。请参阅打印屏幕的更新问题。回答很好,但我更喜欢使用某种内置的Windows util,而不必编写自己的程序来解决它。回答很好,但我不希望像您所说的那样使用任何第三方库。然而,由于这是迄今为止最好的答案,我会将其标记为已接受,直到有更好的选择为止。:)我确实从中得到了一个值,但它必须被修改。您的代码结果为:base64-valueAQAB
。但是,使用$cert.PrivateKey.ToXmlString(1)
然后使用RSA Key Converter-XML将其转换为PEM,我确实可以在base64中获得私钥。不过,我还没有找到一种使用内置Windows util实现这一点的方法。