Python 如何在不直接访问私钥的情况下创建x.509证书?

Python 如何在不直接访问私钥的情况下创建x.509证书?,python,openssl,x509,Python,Openssl,X509,使用HSM,我可以下载RSA 4096的公钥,并可以使用HSM使用相应的私钥加密blob,而我无法下载私钥。 我试图找到如何使用HSMAPI的参考资料,以便自己构建X509证书。我可以在python中找到下面的例子,包装openssl库。 它几乎完成了所有的工作,但是 from OpenSSL import crypto, SSL from socket import gethostname from pprint import pprint from time import gmtime, m

使用HSM,我可以下载RSA 4096的公钥,并可以使用HSM使用相应的私钥加密blob,而我无法下载私钥。 我试图找到如何使用HSMAPI的参考资料,以便自己构建X509证书。我可以在python中找到下面的例子,包装openssl库。 它几乎完成了所有的工作,但是

from OpenSSL import crypto, SSL
from socket import gethostname
from pprint import pprint
from time import gmtime, mktime

CERT_FILE = "selfsigned.crt"
KEY_FILE = "private.key"

def create_self_signed_cert():

    # create a key pair
    k = crypto.PKey()
    k.generate_key(crypto.TYPE_RSA, 1024)

    # create a self-signed cert
    cert = crypto.X509()
    cert.get_subject().C = "UK"
    cert.get_subject().ST = "London"
    cert.get_subject().L = "London"
    cert.get_subject().O = "Dummy Company Ltd"
    cert.get_subject().OU = "Dummy Company Ltd"
    cert.get_subject().CN = gethostname()
    cert.set_serial_number(1000)
    cert.gmtime_adj_notBefore(0)
    cert.gmtime_adj_notAfter(10*365*24*60*60)
    cert.set_issuer(cert.get_subject())
    cert.set_pubkey(k)
    cert.sign(k, 'sha1')

    open(CERT_FILE, "wt").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
    open(KEY_FILE, "wt").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))

create_self_signed_cert()
我最希望的是更换线路

   cert.sign(k, 'sha1')

通过使用“cert”结构的“导出”对我的HSM的API进行相应调用。有可能吗?

所以经过一天的研究,我在一家公司找到了一个令人满意的答案。虽然似乎有一些Python示例介绍了如何使用pyasn1通过Python构建证书,但最健壮的示例似乎是java中使用boucycastle库的示例。我还找到了一个强有力的答案,如何将其与openssl结合在一起(主要是第3点和第4点),但这种方法远远超出了我的能力。

当您希望其他人(如您的HSM)为您签署证书时,标准方法是生成一个(CSR)并将CSR发送给签署人。CSR可以包含在生成证书时可以设置的所有字段,这些值将反映在生成的证书中

虽然您可以使用您正在使用的OpenSSL库来实现这一点,但请参阅他们的文档(我引述)中“强烈建议”您改用该库。(它们由同一组人维护。)

在加密库中,您可以使用创建CSR。引用他们的文档:

>>> from cryptography import x509
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import rsa
>>> from cryptography.x509.oid import AttributeOID, NameOID
>>> private_key = rsa.generate_private_key(
...     public_exponent=65537,
...     key_size=2048,
... )
>>> builder = x509.CertificateSigningRequestBuilder()
>>> builder = builder.subject_name(x509.Name([
...     x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
... ]))
>>> builder = builder.add_extension(
...     x509.BasicConstraints(ca=False, path_length=None), critical=True,
... )
>>> builder = builder.add_attribute(
...     AttributeOID.CHALLENGE_PASSWORD, b"changeit"
... )
>>> request = builder.sign(
...     private_key, hashes.SHA256()
... )
>>> isinstance(request, x509.CertificateSigningRequest)
True
要以通常用于发送CSR的格式呈现CSR,请执行以下操作:

>>> from cryptography.hazmat.primitives import serialization
>>> request.public_bytes(serialization.Encoding.PEM)

如果有可能的话,那不是完全违背了获得证书的目的吗?一点也不。您可以使用私钥生成证书。在基于硬件的设备中进行加密,而不是在计算机上的文件中进行加密,这实际上是您想要的方式。通常,OpenSSL或其他台式机将支持和HSM透明对话的引擎。在我的例子中,我希望能够以编程的方式完成它。