19

正如标题所示,我想在不使用 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

我可以像这样得到公钥:

(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 的命令,但出现以下错误。

私钥不是纯文本可导出的

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

在此处输入图像描述

与 MMC 证书中的证书导出向导类似,仅.pfx在包含密钥时导出到可用。

在此处输入图像描述

4

7 回答 7

6

我遇到了同样的问题,并在 PS Gallery的PSPKI Powershell 模块的帮助下解决了它。虽然我知道您正在寻找一种最好使用 Windows 中的某些内置功能的解决方案,但从 PS Gallery 安装模块可能是可以接受的。至少在我的情况下。

首先安装 PSPKI 模块(我假设 PSGallery 存储库已经设置好了):

Install-Module -Name PSPKI

PSPKI 模块提供了一个 Cmdlet Convert-PfxToPem,它将 pfx 文件转换为 pem 文件,其中包含作为 base64 编码文本的证书和 pirvate 密钥:

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

现在,我们需要做的就是用一些正则表达式的魔法来分割 pem 文件。例如,像这样:

(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"
于 2020-11-03T10:33:21.803 回答
1

基于 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 字符串是你要找的吗?

于 2021-06-05T18:46:50.777 回答
1

试试这个以 Pkcs8 格式导出私钥的脚本

Azure PowerShell - 从 SSL 证书中提取 PEM

于 2021-07-21T12:59:38.760 回答
0

如果我理解正确 certutil 应该为你做。

certutil -exportPFX -p "ThePasswordToKeyonPFXFile" my [serialNumberOfCert] [fileNameOfPFx]

于 2019-08-31T20:24:09.420 回答
0

尝试这样的事情:

$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
于 2020-06-24T22:04:00.410 回答
0

可以导出时,可以使用多个 API 将密钥导出为多种格式。最常见的是 PKCS#8(行业标准)和 XML(MSFT 专有 afaik)。

看看这些答案:

于 2020-06-15T08:13:44.477 回答
0

嗯。您是否尝试过打开证书存储并以这种方式获取私钥?可以肯定的是,这仅适用于 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()

于 2020-10-23T03:14:45.763 回答