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

时间:2018-10-22 12:49:44

标签: windows powershell certificate certificate-store

正如标题所示,我想不使用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之类的在线工具。

PSVersion:

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

7 个答案:

答案 0 :(得分:1)

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

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

let currentActive = 1; // remember where we are now
const maxItems = 3; // how many items?

setInterval(
    function(){
        // - remove 'active' from the currentActive element
        currentActive++;
        // if the currentActive > maxitems, set it back to 1
        // - add 'active' to the new currentActive element
    }, 
    5000
);

PSPKI模块提供了一个Cmdlet Install-Module -Name PSPKI ,该Cmdlet将pfx文件转换为包含证书和证书密钥(作为base64编码文本)的pem文件:

Convert-PfxToPem

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

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

答案 1 :(得分:0)

如果我正确理解certutil应该为您完成。

{ "ipcMode": null, "executionRoleArn": "arn:aws:iam::xxxxxxxxxxx:role/ecsTaskExecutionRole", "containerDefinitions": [ { "dnsSearchDomains": null, "logConfiguration": { "logDriver": "awslogs", "secretOptions": null, "options": { "awslogs-group": "/ecs/awxtest", "awslogs-region": "xxxxxxxx", "awslogs-stream-prefix": "ecs" } }, "entryPoint": null, "portMappings": [], "command": null, "linuxParameters": null, "cpu": 0, "environment": [], "resourceRequirements": null, "ulimits": null, "dnsServers": null, "mountPoints": [], "workingDirectory": null, "secrets": null, "dockerSecurityOptions": null, "memory": null, "memoryReservation": 100, "volumesFrom": [], "stopTimeout": null, "image": "xxxxxxxxxx", "startTimeout": null, "dependsOn": null, "disableNetworking": null, "interactive": null, "healthCheck": null, "essential": true, "links": null, "hostname": null, "extraHosts": null, "pseudoTerminal": null, "user": null, "readonlyRootFilesystem": null, "dockerLabels": null, "systemControls": null, "privileged": null, "name": "memcached" }, { "dnsSearchDomains": null, "logConfiguration": { "logDriver": "awslogs", "secretOptions": null, "options": { "awslogs-group": "/ecs/awxtest", "awslogs-region": "xxxxxxxxxx", "awslogs-stream-prefix": "ecs" } }, "entryPoint": [ "/bin/sh", "-c", "echo $SECRET_BASE64 | base64 -d > /etc/tower/SECRET_KEY", "/usr/bin/launch_awx_task.sh" ], "portMappings": [], "command": [], "linuxParameters": null, "cpu": 0, "environment": [ { "name": "MEMCACHED_PORT", "value": "11211" }, { "name": "SECRET_BASE64", "value": "${secret_base64}" }, { "name": "DATABASE_NAME", "value": "awx" }, { "name": "AWX_ADMIN_PASSWORD", "value": "xxxxxxxxxx" }, { "name": "DATABASE_PORT", "value": "5432" }, { "name": "RABBITMQ_PASSWORD", "value": "guest" }, { "name": "AWX_ADMIN_USER", "value": "admin" }, { "name": "RABBITMQ_PORT", "value": "5672" }, { "name": "RABBITMQ_USER", "value": "guest" }, { "name": "MEMCACHED_HOST", "value": "localhost" }, { "name": "RABBITMQ_VHOST", "value": "awx" }, { "name": "RABBITMQ_HOST", "value": "localhost" }, { "name": "DATABASE_PASSWORD", "value": "xxxxxxxxxx" }, { "name": "DATABASE_USER", "value": "awx" } ], "resourceRequirements": null, "ulimits": null, "dnsServers": null, "mountPoints": [], "workingDirectory": null, "secrets": null, "dockerSecurityOptions": null, "memory": null, "memoryReservation": 1536, "volumesFrom": [], "stopTimeout": null, "image": "xxxxxxxxxx", "startTimeout": null, "dependsOn": null, "disableNetworking": null, "interactive": null, "healthCheck": null, "essential": true, "links": null, "hostname": null, "extraHosts": null, "pseudoTerminal": null, "user": null, "readonlyRootFilesystem": null, "dockerLabels": null, "systemControls": null, "privileged": null, "name": "awx-task" }, { "dnsSearchDomains": null, "logConfiguration": { "logDriver": "awslogs", "secretOptions": null, "options": { "awslogs-group": "/ecs/awxtest", "awslogs-region": "xxxxxxxxxx", "awslogs-stream-prefix": "ecs" } }, "entryPoint": [ "/bin/sh", "-c", "echo $SECRET_BASE64 | base64 -d > /etc/tower/SECRET_KEY", "usr/bin/launch_awx.sh" ], "portMappings": [], "command": [], "linuxParameters": null, "cpu": 0, "environment": [ { "name": "MEMCACHED_PORT", "value": "11211" }, { "name": "SECRET_BASE64", "value": "${secret_base64}" }, { "name": "DATABASE_NAME", "value": "awx" }, { "name": "AWX_ADMIN_PASSWORD", "value": "xxxxxxxxxx" }, { "name": "DATABASE_HOST", "value": "xxxxxxxxxx" }, { "name": "DATABASE_PORT", "value": "5432" }, { "name": "RABBITMQ_PASSWORD", "value": "guest" }, { "name": "AWX_ADMIN_USER", "value": "admin" }, { "name": "RABBITMQ_PORT", "value": "5672" }, { "name": "RABBITMQ_USER", "value": "guest" }, { "name": "MEMCACHED_HOST", "value": "localhost" }, { "name": "RABBITMQ_VHOST", "value": "awx" }, { "name": "RABBITMQ_HOST", "value": "localhost" }, { "name": "DATABASE_PASSWORD", "value": "xxxxxxxxxx" }, { "name": "DATABASE_USER", "value": "awx" } ], "resourceRequirements": null, "ulimits": null, "dnsServers": null, "mountPoints": [], "workingDirectory": null, "secrets": null, "dockerSecurityOptions": null, "memory": null, "memoryReservation": 1536, "volumesFrom": [], "stopTimeout": null, "image": "xxxxxxxxxx", "startTimeout": null, "dependsOn": null, "disableNetworking": null, "interactive": null, "healthCheck": null, "essential": true, "links": null, "hostname": null, "extraHosts": null, "pseudoTerminal": null, "user": null, "readonlyRootFilesystem": null, "dockerLabels": null, "systemControls": null, "privileged": null, "name": "awx-web" }, { "dnsSearchDomains": null, "logConfiguration": { "logDriver": "awslogs", "secretOptions": null, "options": { "awslogs-group": "/ecs/awxtest", "awslogs-region": "xxxxxxxxxx, "awslogs-stream-prefix": "ecs" } }, "entryPoint": [ "/bin/sh", "-c", "/launch.sh" ], "portMappings": [], "command": null, "linuxParameters": null, "cpu": 0, "environment": [ { "name": "RABBITMQ_ERLANG_COOKIE", "value": "cookiemonster" }, { "name": "RABBITMQ_DEFAULT_VHOST", "value": "localhost" } ], "resourceRequirements": null, "ulimits": null, "dnsServers": null, "mountPoints": [], "workingDirectory": null, "secrets": null, "dockerSecurityOptions": null, "memory": null, "memoryReservation": 300, "volumesFrom": [], "stopTimeout": null, "image": "xxxxxxxxxxx", "startTimeout": null, "dependsOn": null, "disableNetworking": null, "interactive": null, "healthCheck": null, "essential": true, "links": null, "hostname": null, "extraHosts": null, "pseudoTerminal": null, "user": null, "readonlyRootFilesystem": null, "dockerLabels": null, "systemControls": null, "privileged": null, "name": "awx-rabbitmq" } ], "memory": "4096", "taskRoleArn": "arn:aws:iam::xxxxxxxxxx:role/awx_task", "family": "awxtest", "pidMode": null, "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc", "cpu": "2048", "inferenceAccelerators": null, "proxyConfiguration": null, "volumes": [], "tags": [] }

答案 2 :(得分:0)

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

看看这些答案:

答案 3 :(得分: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

答案 4 :(得分: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()

答案 5 :(得分:0)

基于 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 字符串吗?

答案 6 :(得分:0)

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

Azure PowerShell - Extract PEM from SSL certificate