使用python中的CA根证书从客户端签署CSR

时间:2014-04-16 08:25:13

标签: python-2.7 openssl ssl-certificate m2crypto pyopenssl

我是python的新手并且还在学习它,所以我的问题可能有些天真。请忍受它;)

问题是客户端将发送CSR,我想用我的CA根证书签名并将签名的证书返回给客户。

我一直在使用此命令使用命令行

执行此操作

openssl x509 -req -in device.csr -CA root.pem -CAkey root.key -CAcreateserial -out device.crt -days 500

我想用python实现同样的东西。我遇到了openssl pyopenssl

的python库

可以使用这个库吗?怎么样 ?或者我想去M2Crypto吗?

2 个答案:

答案 0 :(得分:11)

你确实可以使用pyOpenSSL。正如您所说,您已经拥有CA根证书和私钥,并且CSR将由客户端发送,然后您可以使用加密功能从文件中读取所有这些(CA证书,私钥和设备CSR)或管理他们在缓冲区。

使用以下功能开始。检查python解释器上的dir(crypto) and crypto.function_name.__doc__以获取更多信息:)你需要从pyOpenSSL导入crypto

  1. crypto.load_certificate_request() - 获取设备CSR obj
  2. crypto.load_privatekey() - 获取CA私钥的私钥obj
  3. crypto.load_certificate() - 获取CA根证书
  4. 然后你可以编写简单的函数来返回证书

    def create_cert():
        cert = crypto.X509()
        cert.set_serial_number(serial_no)
        cert.gmtime_adj_notBefore(notBeforeVal)
        cert.gmtime_adj_notAfter(notAfterVal)
        cert.set_issuer(caCert.get_subject())
        cert.set_subject(deviceCsr.get_subject())
        cert.set_pubkey(deviceCsr.get_pubkey())
        cert.sign(CAprivatekey, digest)
        return cert
    

    其中 caCert deviceCsr CAprivatekey 是来自以上三个功能的值。 既然您已获得证书,则可以使用crypto.dump_certificate(crypto.FILETYPE_PEM, cert)将文件写入文件,并使用您选择的文件名。

    您可以根据自己的要求修改此功能。在此之后,您可以使用openssl命令验证带有CA根证书的生成的设备证书,例如openssl verify -CApath <CA cert path> <name of device cert file>

    您还可以从github中查看一些示例。 M2Crypto ExamplepyOpenSSL example

    希望这可以让您了解实施

答案 1 :(得分:2)

pyOpenSSL 的维护者建议使用 cryptography 模块进行 X509 操作(请参阅文档页面顶部的注释:https://www.pyopenssl.org/en/stable/api/crypto.html)。

以下是从 CA 签署的 CSR 创建证书的代码:

def sign_certificate_request(csr_cert, ca_cert, private_ca_key):
    cert = x509.CertificateBuilder().subject_name(
        csr_cert.subject
    ).issuer_name(
        ca_cert.subject
    ).public_key(
        csr_cert.public_key()
    ).serial_number(
        x509.random_serial_number()
    ).not_valid_before(
        datetime.utcnow()
    ).not_valid_after(
        # Our certificate will be valid for 10 days
        datetime.utcnow() + timedelta(days=10)
    # Sign our certificate with our private key
    ).sign(private_ca_key, hashes.SHA256())

    # return DER certificate
    return cert.public_bytes(serialization.Encoding.DER)
  • csr_cert 是 cryptography CSR 证书对象 - 可以从带有 x509.load_der_x509_csr() 的文件中加载
  • ca_cert 是 cryptography 证书对象 - 可以从文件中加载 x509.load_pem_x509_certificate()
  • private_ca_key 是 cryptography 私钥对象 - 可以从带有 serialization.load_pem_private_key() 的文件中加载