从PKCS12文件中提取公钥/私钥以供稍后在SSH-PK身份验证中使用

230

我想从我的PKCS#12文件中提取公钥和私钥,以备后续在SSH公钥身份验证中使用。

目前,我通过ssh-keygen生成密钥,并将其放入. ssh/authorized_key中,相应地放在客户端的某个位置。

将来,我想使用来自 PKCS#12 容器的密钥,因此我必须先从PKCS#12中提取公钥,然后将它们放入. ssh/authorized_keys文件中。 是否有可能通过openssl使其工作? PKCS#12中的密钥是否兼容于SSH公钥身份验证?

7个回答

340

您可以使用以下命令从 PKCS#12 容器中提取公钥/私钥:

  • PKCS#1 Private key

    openssl pkcs12 -in yourP12File.pfx -nocerts -out privateKey.pem
    
  • Certificates:

    openssl pkcs12 -in yourP12File.pfx -clcerts -nokeys -out publicCert.pem
    

8
命令可以正常工作,但私钥是以PKCS1格式导出的,我需要PKCS8格式...有没有我遗漏的选项可以实现这一点?例如,它导出的是 "-----BEGIN RSA PRIVATE KEY-----",但我需要 "-----BEGIN PRIVATE KEY-----"。 - edthethird
6
您可以尝试使用“openssl rsa -in privateKey.pem -out private.pem”来实现这一点。 - Francois
34
要获取PKCS8,添加“-nodes”标志。 - Christopher K.
10
若要无需密码导出,请添加-passout pass:。它需要以pass:我的密码格式的参数作为输入。https://dev59.com/Dl4c5IYBdhLWcg3wz9FG#27497899 - nidheeshdas
3
@ChristopherK. 谢谢!那对我来说很有用。添加“-nodes”可以正确导出密钥。 - TecHunter
显示剩余2条评论

98

通过一些格式转换,这是可以实现的。

要以openssh可以使用的格式提取私钥:

openssl pkcs12 -in pkcs12.pfx -nocerts -nodes | openssl rsa > id_rsa

将私钥转换为公钥:

openssl rsa -in id_rsa -pubout | ssh-keygen -f /dev/stdin -i -m PKCS8

为了提取以openssh可用格式的公钥:

openssl pkcs12 -in pkcs12.pfx -clcerts -nokeys | openssl x509 -pubkey -noout | ssh-keygen -f /dev/stdin -i -m PKCS8

3
谢谢!我需要的是第一行。只需提取密钥,不加密,这样它就可以通过大多数CDN自动化系统安装。 - BTC

21

OpenSSH无法直接使用PKCS#12文件。正如其他人建议的那样,您必须以PEM格式提取私钥,从而将您从OpenSSL之地带到OpenSSH。这里提到的其他解决方案对我不起作用。我使用OS X 10.9 Mavericks(目前为10.9.3)与“预装”的实用程序(OpenSSL 0.9.8y,OpenSSH 6.2p2)。

首先,请提取一个以PEM格式保存的私钥,它将被OpenSSH直接使用:

openssl pkcs12 -in filename.p12 -clcerts -nodes -nocerts | openssl rsa > ~/.ssh/id_rsa

我强烈建议使用密码加密私钥:

openssl pkcs12 -in filename.p12 -clcerts -nodes -nocerts | openssl rsa -passout 'pass:Passw0rd!' > ~/.ssh/id_rsa

显然,在命令行上写明文密码也不安全,因此您应该从历史记录中删除最后一个命令,或者确保它不会出现在历史记录中。不同的shell有不同的方法。您可以在Bash和许多其他shell中使用空格前缀来防止命令被保存到历史记录中。以下是如何在Bash中从历史记录中删除命令的方法:

history -d $(history | tail -n 2 | awk 'NR == 1 { print $1 }')

或者,您可以使用不同的方式将私钥密码传递给OpenSSL - 参考OpenSSL文档中有关密码短语参数的说明

然后,创建一个可添加到authorized_keys文件的OpenSSH公钥:

ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub

“| openssl rsa” 这个东西是干什么用的? - Snekse
1
@Snekse 它确保输出中只有私钥。在我的情况下,它创建了带有一些“垃圾”(如Bag属性)的身份文件(〜/ .ssh / id_rsa),而没有使用 | openssl rsa。我猜OpenSSH和其他使用身份文件的实用程序可以处理那些垃圾(我还没有尝试过),但是我习惯于仅提供必要的数据,特别是如果涉及到安全问题。 - F4-Z4
1
以下答案对我很有帮助,可以让我在终端中访问PEM格式的私钥并进行复制/粘贴:openssl pkcs12 -in filename.p12 -clcerts -nodes -nocerts - Andrew Aarestad

11

方案1:

从jks中提取P12

keytool -importkeystore -srckeystore MyRootCA.jks -destkeystore MyRootCA.p12 -deststoretype PKCS12

从P12提取PEM并编辑文件,以及从crt文件提取PEM

openssl pkcs12 -in MyRootCA.p12 -clcerts -nokeys -out MyRootCA.crt

从jks中提取密钥

openssl pkcs12 -in MyRootCA.p12 -nocerts -out encryptedPrivateKey.pem
openssl rsa -in encryptedPrivateKey.pem -out decryptedPrivateKey.key

解决方案2:

将PEM和encryptedPrivateKey提取到txt文件中```

openssl pkcs12 -in MyRootCA.p12 -out keys_out.txt

解密私钥

openssl rsa -in encryptedPrivateKey.key [-outform PEM] -out decryptedPrivateKey.key

1
回答问题时,突出命令很有帮助。您可以通过在命令前后添加三个反引号来实现,因此```echo hello```变成echo hello - PatS

2
更新:我注意到我的回答只是一个很差的副本,而在https://unix.stackexchange.com/...上有一个解释得很好的问题,由BryKKan提出。

以下是其中的一段摘录:

openssl pkcs12 -in <filename.pfx> -nocerts -nodes | sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' > <clientcert.key>

openssl pkcs12 -in <filename.pfx> -clcerts -nokeys | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > <clientcert.cer>

openssl pkcs12 -in <filename.pfx> -cacerts -nokeys -chain | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > <cacerts.cer>

3
添加一些解释会使这个答案更加有用。 - mx0

2
接受的答案是正确的命令,我只想添加一件事情,当提取密钥时,如果您将PEM密码("输入PEM密码短语:" )留空,则只会提取localKeyID而不是完整密钥。要获取完整的密钥,必须在运行以下命令时指定PEM密码。
请注意,在导入密码方面,您可以为"输入导入密码:" 指定实际密码,也可以将此密码留空:
openssl pkcs12 -in yourP12File.pfx -nocerts -out privateKey.pem

3
这应该是对被采纳答案的评论,而不是答案本身。 - Styx

1
据我所知,PKCS#12只是一个证书/公钥/私钥存储库。如果您从PKCS#12文件中提取了公钥,并且以 PEM 格式提取,则OpenSSH应该能够使用它。您可能已经知道,为了将其用于ssh-public-key身份验证,您还需要相应的私钥(也以 PEM 格式)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接