如何从Windows证书管理器导出私钥?

时间:2018-08-17 21:56:45

标签: javascript node.js ssl https pki

我正在Windows环境中进行开发。

我的公司充当内部使用的https应用程序的自己的证书颁发机构,并且我已经从我们的系统中获得了证书(对于我构建的仅供内部使用的Web服务器)。

使用证书管理器,我可以导出证书。但是,从证书管理器中导出证书时,“导出私钥”单选按钮显示为灰色。 <-我试图解决此问题,但未成功。

有人有什么建议吗?

我正在使用Node JS(带有Express)进行开发。

否则,我无法为https.createServer配置sslOptions对象。

谢谢!

4 个答案:

答案 0 :(得分:3)

恢复私钥标记为不可导出的证书

我们需要导出IIS7 SSL证书的私钥,以便将其导入在同一域下不同端口上运行的node.js HTTPS项目中。

我们意识到证书已经失去了导出私钥的能力。该证书最近已使用旧的CSR重新发布,但是以某种方式将新证书的私钥标记为不可导出,而过去的证书具有可导出的私钥。幸运的是,我们有一个以前的证书可与可导出的私钥一起使用。互联网上有指南,如果没有旧证书,以下过程可能会起作用,但在我们的情况下,它可能不起作用,可能是因为证书已重新颁发。

免责声明:以下过程对您的计算机没有干扰,需要VM配合使用。如果成功,则您将导出您的私钥。如果失败,那么您唯一的选择是创建带有可导出私钥的CSR,然后重新颁发证书并重新配置域。

使用mmc,我们将两个证书都导入了“本地计算机\个人”。

注意:您要导入证书的位置很重要!

enter image description here

我们使用不可导出的私钥找到了证书的指纹:

enter image description here

在此示例中,拇指为693867F321B5764E324F3FB8C5CBCE03CDA3C2A3。

重要提示:拇指必须大写!!!

这时,根据您问题的根本原因,我们建议 启动命令提示符并输入以下命令(可能如此) 解决您的问题:

certutil -repairstore my 693867F321B5764E324F3FB8C5CBCE03CDA3C2A3

如果问题仍未解决,并且私钥仍然不可导出,请继续...

使用PowerShell我们确定了私钥存储并复制到C:\

enter image description here

$a = get-item cert:\LocalMachine\My\693867F321B5764E324F3FB8C5CBCE03CDA3C2A3
$a.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName

此命令显示私钥存储为:

00998a33dbff25a91050b3b1bf9001ef_a5968f4a-5244-4993-830a-363​​efe3adated

然后使用NirSoft PsExec64在系统帐户上启动“提升的命令提示符”,并使用/ G和/ H将密钥库复制/解密到C:\。

PsExec64.exe -s -i cmd
xcopy /G /H "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys\00998a33dbff25a91050b3b1bf9001ef_a5968f4a-5244-4993-830a-363efe3adaed" c:\

enter image description here

我们创建了一个VMware并复制了证书和私钥存储:

enter image description here

使用MMC,我们将两个证书都导入了 Local Computer \ Personal

enter image description here

enter image description here

在导入期间,我们确保对于带有私钥的证书,我们将私钥标记为可导出:

enter image description here

因此,两个证书都被导入了,但是正如预期的那样,只有一个带有锁定图标,表明它具有私钥:

enter image description here

在VM上使用Power Shell,我们从Microsoft密码学获得了计算机的GUID,并使用了此GUID来将私钥存储复制到正确的位置。

Get-ItemProperty Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\ -Name MachineGuid

返回:a73d2e44-7a45-486a-97d3-b9d97bf556fa。 在以下命令中,您需要将旧计算机的GUID替换为新计算机,GUID在第一个破折号(-)之后。命令语法是这样的:

Move-Item "C:\<certificate-store>_<old-computer-guid>" "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys\<certificate-store>_<vm-computer-guid>"

因此,根据前面步骤中得出的标识符,它应该看起来像这样:

Move-Item "C:\00998a33dbff25a91050b3b1bf9001ef_a5968f4a-5244-4993-830a-363efe3adaed" "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys\00998a33dbff25a91050b3b1bf9001ef_a73d2e44-7a45-486a-97d3-b9d97bf556fa"

然后,我们使用有问题的证书的拇指来运行certutil进行修复!

certutil -repairstore my 693867F321B5764E324F3FB8C5CBCE03CDA3C2A3

您应该看到类似这样的内容:

enter image description here

刷新MMC之后,您将使两个证书都具有一个私钥图标:

enter image description here

因此,继续并使用私钥导出证书:

enter image description here

SOS:确保您将私钥标记为可过期!!!

enter image description here

enter image description here

接下来,将PFX文件复制回到您的node.js服务器计算机,并在现有问题证书的顶部将其导入。

导入新证书后,您可以删除旧证书。

下一步,从服务器重新导出证书,仅用于完整性检查。您应该会看到不再变灰的导出私钥!

enter image description here

SOS:确保您将私钥标记为可过期!!!

enter image description here

要导出node.js的私钥,我们使用了DigiCert Utility工具:

enter image description here

要使用node.js将PFX转换为PEM,我们使用了OpenSSL:

openssl pkcs12 -in www_xxx_com.pfx -clcerts -nokeys -out www_xxx_com.pem

要使用证书,请使用node.js在node.exe路径中创建一个SLL文件夹,然后在其中复制以下项目:

  1. 私钥文件(.key)
  2. 证书文件(.pem)
  3. 权威证书文件(.crt)

注意:权威证书文件与证书提供商提供的证书一起提供。

enter image description here

最后,您可以使用以下代码加载证书和私钥:

  var https_options = {
    key: fs.readFileSync("C:\\nodejs\\ssl\\www_xxx_com.key"),
    cert: fs.readFileSync("C:\\nodejs\\ssl\\www_xxx_com.pem"),
    ca: [
      fs.readFileSync('C:\\nodejs\\ssl\\DigiCertCA.crt')      
    ]
  };
  require('https').createServer(https_options, app).listen(PORT);

或者根据node.js的安装位置,相应地编辑路径。

答案 1 :(得分:0)

可能的原因是:

  1. 如果您的CA不是Microsoft的(或者即使不是,但是您在另一个盒子上创建了证书),则仅导出证书,而不导出私钥。对于Windows,这意味着您必须导出/导入import dash import dash_auth import dash_core_components as dcc import dash_html_components as html from dash.dependencies import Input, Output USERNAME_PASSWORD_PAIRS = [ ['JamesBond', '007'],['LouisArmstrong', 'satchmo'] ] app = dash.Dash() auth = dash_auth.BasicAuth(app,USERNAME_PASSWORD_PAIRS) server = app.server app.layout = html.Div([ dcc.RangeSlider( id='range-slider', min=-5, max=6, marks={i:str(i) for i in range(-5, 7)}, value=[-3, 4] ), html.H1(id='product') # this is the output ], style={'width':'50%'}) @app.callback( Output('product', 'children'), [Input('range-slider', 'value')]) def update_value(value_list): return value_list[0]*value_list[1] if __name__ == '__main__': app.run_server() .pfx文件(仅证书),而不是导出/导入.p12.cer文件(组合的证书和私钥) )。

  2. 假设您的CA是Microsoft的,则在颁发证书的模板上未启用允许导出私钥

  3. 同样,假设您的CA是Microsoft,如果您使用证书管理器中的高级操作-> 自定义请求... 选项,并选择为< strong>继续进行,没有注册政策,您没有在证书属性私有密钥标签下启用使私钥可导出对话。

答案 2 :(得分:0)

我有同样的问题。

使用CMD运行命令

 certutil –repairstore my serialnumber

您可以从证书详细信息选项卡中找到序列号。在运行命令之前,请删除所有空格。

示例

certutil –repairstore my 25oA445521C8E9

更多详情

Check the link

答案 3 :(得分:0)

存在访问权限不足的可能性,我的意思是您的密钥文件已存储在“C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys”,并且可能要测试一些您删除机器密钥并将它们作为备份的方法,在您的场景经过测试之后,您需要在那一刻恢复这些文件,您必须提供对每个文件用户的访问权限,例如“每个人”,“ 系统”、“管理员”、“IIS_IUSR”等...

在此之后,您可以在 IIS 中访问这些证书以将它们分配给任何托管站点,

我遇到了同样的问题,我删除了机器密钥,这些密钥在服务器重新启动后生效,一旦服务器重新启动,您关联的 SSL 证书将自动删除,因为系统无法访问这些文件,在这种情况下我们必须提供访问权限手动