在 Windows 上不使用 OpenSSL 从 pfx 文件或证书存储中提取私钥
Extract private key from pfx file or certificate store WITHOUT using OpenSSL on Windows
如标题所示,我想在不使用 OpenSSL 或任何其他第三方工具的情况下导出我的私钥。如果我需要 .cer
文件或 .pfx
文件,我可以通过 MMC 或 PowerShell 轻松导出这些文件 pkiclient
但我找不到获取私钥的方法。
https://docs.microsoft.com/en-us/powershell/module/pkiclient/export-certificate?view=win10-ps
使用像 https://www.sslshopper.com/ssl-converter.html 这样的在线工具是不行的。
PS 版本:
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
我可以这样获得 public 密钥:
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetPublicKey()
并像这样导出整个证书:
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetRawCertData()
结果来自
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 的命令,但出现以下错误。
Private key is NOT plain text exportable
certutil -exportPFX -p "myPassword" -privatekey -user my <Certificate Serial Number> C:\localhost.pfx
类似于 MMC 证书中的证书导出向导,只有包含密钥才能导出到 .pfx
。
如果我理解正确,certutil 应该会为您完成。
certutil -exportPFX -p "ThePasswordToKeyonPFXFile" my [serialNumberOfCert] [fileNameOfPFx]
密钥在可导出时可以使用多种 API 导出为多种格式。最常见的是 PKCS#8(行业标准)和 XML(MSFT properitary afaik)。
看看这些答案:
- Convert RSACryptoServiceProvider RSA XML key to PKCS8
尝试这样的事情:
$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
嗯。您是否尝试过打开证书商店并以这种方式获取私钥?很确定这只适用于 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 画廊的 PSPKI Powershell module 的帮助下解决了这个问题。虽然我知道您正在寻找一种解决方案,最好使用 Windows 中的某些内置功能,但从 PS 库安装模块可能是可以接受的。至少我是这样。
首先安装 PSPKI 模块(我假设 PSGallery 存储库已经设置好):
Install-Module -Name PSPKI
PSPKI 模块提供了一个 Cmdlet Convert-PfxToPem
,它将 pfx-file 转换为 pem-file,其中包含证书和 pirvate 密钥作为 base64 编码的文本:
Convert-PfxToPem -InputFile C:\path\to\pfx\file.pfx -Outputfile C:\path\to\pem\file.pem
现在,我们需要做的就是用一些正则表达式魔术拆分 pem-file。例如,像这样:
(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"
基于 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 字符串吗?
试试这个导出 Pkcs8 格式私钥的脚本
Azure PowerShell - Extract PEM from SSL certificate
如标题所示,我想在不使用 OpenSSL 或任何其他第三方工具的情况下导出我的私钥。如果我需要 .cer
文件或 .pfx
文件,我可以通过 MMC 或 PowerShell 轻松导出这些文件 pkiclient
但我找不到获取私钥的方法。
https://docs.microsoft.com/en-us/powershell/module/pkiclient/export-certificate?view=win10-ps
使用像 https://www.sslshopper.com/ssl-converter.html 这样的在线工具是不行的。
PS 版本:
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
我可以这样获得 public 密钥:
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetPublicKey()
并像这样导出整个证书:
(Get-PfxCertificate -FilePath C:\Users\oscar\Desktop\localhost.pfx).GetRawCertData()
结果来自
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 的命令,但出现以下错误。
Private key is NOT plain text exportable
certutil -exportPFX -p "myPassword" -privatekey -user my <Certificate Serial Number> C:\localhost.pfx
类似于 MMC 证书中的证书导出向导,只有包含密钥才能导出到 .pfx
。
如果我理解正确,certutil 应该会为您完成。
certutil -exportPFX -p "ThePasswordToKeyonPFXFile" my [serialNumberOfCert] [fileNameOfPFx]
密钥在可导出时可以使用多种 API 导出为多种格式。最常见的是 PKCS#8(行业标准)和 XML(MSFT properitary afaik)。
看看这些答案:
- Convert RSACryptoServiceProvider RSA XML key to PKCS8
尝试这样的事情:
$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
嗯。您是否尝试过打开证书商店并以这种方式获取私钥?很确定这只适用于 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 画廊的 PSPKI Powershell module 的帮助下解决了这个问题。虽然我知道您正在寻找一种解决方案,最好使用 Windows 中的某些内置功能,但从 PS 库安装模块可能是可以接受的。至少我是这样。
首先安装 PSPKI 模块(我假设 PSGallery 存储库已经设置好):
Install-Module -Name PSPKI
PSPKI 模块提供了一个 Cmdlet Convert-PfxToPem
,它将 pfx-file 转换为 pem-file,其中包含证书和 pirvate 密钥作为 base64 编码的文本:
Convert-PfxToPem -InputFile C:\path\to\pfx\file.pfx -Outputfile C:\path\to\pem\file.pem
现在,我们需要做的就是用一些正则表达式魔术拆分 pem-file。例如,像这样:
(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"
基于 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 字符串吗?
试试这个导出 Pkcs8 格式私钥的脚本
Azure PowerShell - Extract PEM from SSL certificate