【问题标题】:Converting PKCS#12 certificate into PEM using OpenSSL使用 OpenSSL 将 PKCS#12 证书转换为 PEM
【发布时间】:2013-02-15 03:30:42
【问题描述】:

我在 Windows 7 上有 OpenSSL x64,我从 openssl-for-windows on Google Code 下载。我正在尝试运行:

openssl pkcs12 -export -in "path.p12" -out "newfile.pem" 

但我得到一个错误。

unable to load private key

如何使用 OpenSSL 从 PKCS#12 存储中提取 PEM 中的证书?

【问题讨论】:

  • @jww 我认为鉴于这个问题已经超过 3 年了,现在发出离题标志有点晚了。
  • 只是一种形式,所以人们知道它的题外话。人们在问同样的离题问题,并引用这个问题。如果人们没有被告知其题外话,那么他们将继续在 Stack Overflow 上提问。
  • @jww 对您链接的元问题的最高投票回答是“应该允许在 Stack Overflow 上提出 DevOps 问题。”我会投票,因为答案满足了我的需求(尽管对我来说,我不是在编程,如果我愿意,我可以很容易地将答案合并到一个程序中)

标签: openssl command pkcs#12


【解决方案1】:
#!/usr/bin/env python3
from optparse import Option
from OpenSSL import crypto
import os
import warnings
from getpass import getpass
warnings.filterwarnings("ignore", category=DeprecationWarning) 

def sanitize_path(path):
    return os.path.expandvars(os.path.expanduser(path))

def main(in_file, out_file, passphrase=None):
    if not passphrase:
        passphrase = getpass(prompt=("SSL Private Key Passphrase: "))
   
    in_file = sanitize_path(in_file)
    out_file = sanitize_path(out_file)
    
    with open(in_file, "rb") as input_file:
        p12 = crypto.load_pkcs12(input_file.read(), passphrase)
        pem = crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey())
    with open(out_file, "w") as output_file:
        output_file.write(pem.decode('utf-8'))

if __name__ == '__main__':
    from optparse import OptionParser
    usage = "usage: %prog  input_file output_file [passphrase]"
    p = OptionParser(usage=usage)
    opt, args = p.parse_args()
    main(*args)

【讨论】:

    【解决方案2】:

    有一个免费的开源 GUI 工具 KeyStore Explorer 可用于加密密钥容器。使用它,您可以将证书或私钥导出到单独的文件中,或将容器转换为另一种格式(jks、pem、p12、pkcs12 等)

    【讨论】:

      【解决方案3】:

      试试:

      openssl pkcs12 -in path.p12 -out newfile.crt.pem -clcerts -nokeys
      openssl pkcs12 -in path.p12 -out newfile.key.pem -nocerts -nodes
      

      之后你有:

      • newfile.crt.pem 中的证书
      • newfile.key.pem 中的私钥

      要将证书和密钥放在同一个文件中而不需要密码,请使用以下内容,因为空密码会导致无法导出密钥:

      openssl pkcs12 -in path.p12 -out newfile.pem -nodes
      

      或者,如果您想为私钥提供密码,请省略 -nodes 并输入密码:

      openssl pkcs12 -in path.p12 -out newfile.pem
      

      如果您需要直接从命令行(例如脚本)输入PKCS#12密码,只需添加-passin pass:${PASSWORD}

      openssl pkcs12 -in path.p12 -out newfile.crt.pem -clcerts -nokeys -passin 'pass:P@s5w0rD'
      

      【讨论】:

      • 私钥和证书是否可以存储在同一个 *.pem 文件中?
      • 对,就是:openssl pkcs12 -in path.p12 -out newfile.pem
      • 要求输入密码。那是什么?
      • @SaurabhChandraPatel 您必须知道证书的密码。这不是找回忘记密码的方法
      • 省略-nodes,私钥不会被提取。
      【解决方案4】:

      如果你会使用 Python,那么如果你有 pyopenssl 模块就更容易了。这里是:

      from OpenSSL import crypto
      
      # May require "" for empty password depending on version
      
      with open("push.p12", "rb") as file:
          p12 = crypto.load_pkcs12(file.read(), "my_passphrase")
      
      # PEM formatted private key
      print crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey())
      
      # PEM formatted certificate
      print crypto.dump_certificate(crypto.FILETYPE_PEM, p12.get_certificate())
      

      【讨论】:

      • 是否有任何理由使用file 而不是open 打开文件?我只是想理解它,因为我将来会使用它(以简化我的解决方案,调用 openssh 作为命令)
      • 不,没有区别。你可以做open("push.p12", 'rb').read()
      • 如果使用 python 3,您可能希望将内容写入文件:with open("push.pem", "wb") as fobj: fobj.write(crypto.dump_certificate(crypto.FILETYPE_PEM, p12.get_certificate())) 写入证书,with open("push.key", "wb") as fobj: fobj.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey())) 写入密钥。
      • 我使用的是python 3.7,在运行上面的例子时,我得到以下信息:“TypeError: initializer for ctype 'char' must be a bytes of length 1, not str” 有什么问题吗用我的密码
      • 为什么创建文件、输入代码、保存并运行它比执行单个命令“更容易”?
      【解决方案5】:

      我有一个 PFX 文件,需要为 NGINX 创建 KEY 文件,所以我这样做了:

      openssl pkcs12 -in file.pfx -out file.key -nocerts -nodes
      

      然后我必须编辑 KEY 文件并删除直到 -----BEGIN PRIVATE KEY----- 的所有内容。之后 NGINX 接受了 KEY 文件。

      【讨论】:

        【解决方案6】:

        您只需要提供一个密码。您可以使用以下语法在同一命令行中执行此操作:

        openssl pkcs12 -export -in "path.p12" -out "newfile.pem" -passin pass:[password]
        

        然后将提示您输入密码以加密输出文件中的私钥。如果要导出未加密的私钥(明文),请在上面的行中包含“节点”选项:

        openssl pkcs12 -export -in "path.p12" -out "newfile.pem" -passin pass:[password] -nodes
        

        更多信息:http://www.openssl.org/docs/apps/pkcs12.html

        【讨论】:

          猜你喜欢
          • 2017-03-16
          • 2013-06-02
          • 2011-03-07
          • 2010-10-22
          • 2023-03-20
          • 2011-06-08
          • 1970-01-01
          • 2014-04-13
          相关资源
          最近更新 更多