Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Windows上不使用OpenSSL从pfx文件或证书存储中提取私钥_Windows_Powershell_Certificate_Certificate Store - Fatal编程技术网

在Windows上不使用OpenSSL从pfx文件或证书存储中提取私钥

在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

正如标题所示,我希望在不使用OpenSSL或任何其他第三方工具的情况下导出私钥。如果我需要
.cer
文件或
.pfx
文件,我可以通过MMC或PowerShell
pkiclient
轻松导出这些文件,但我找不到获取私钥的方法

使用像这样的在线工具是不合适的

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实现这一点的方法。