9

这是使用python解析具有DER格式的X509证书的二进制文件以提取公钥的最佳方法。

4

3 回答 3

19

上述答案有些陈旧(截至 2017 年)。

您可以使用asn1crypto以更好的方式执行此操作:

from asn1crypto.x509 import Certificate

with open("mycert.der", "rb") as f:
    cert = Certificate.load(f.read())

n = cert.public_key.native["public_key"]["modulus"]
e = cert.public_key.native["public_key"]["public_exponent"]

print("{:#x}".format(n))    # prints the modulus (hexadecimal)
print("{:#x}".format(e))    # same, for the public exponent

它相对较新(据我所知,2015 年年中),提供了比已经提到的库更好的界面,并且比pyasn1作者所说的要快得多。

于 2017-05-15T22:33:22.957 回答
12

Python 的内置 SSL 模块和 PyOpenSSL 都没有 API 来提取私钥并访问其信息。M2Crypto 不再维护,并且不适用于 OpenSSL 1.0 和更高版本。

PyOpenSSL 有一个公钥类,但它的功能是有限的:

>>> with open("cert.der", "rb") as f:
...     der = f.read()
... 
>>> import OpenSSL.crypto
>>> x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, der)
>>> pkey = x509.get_pubkey()
>>> dir(pkey)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'bits', 'check', 'generate_key', 'type']
>>> pkey.bits()
4096L
>>> pkey.type() == OpenSSL.crypto.TYPE_RSA
True

Python 3.4 可能会获得 X509 类型,该类型会公开更多信息,例如 SPKI。

于 2013-09-15T01:38:35.197 回答
3

自从我问这个问题以来已经有很长时间了,尽管由于视图的数量,我想描述一下我是如何设法使它起作用的。

通过使用 OpenSSL API,我们可以很容易地以可读的方式打印 DER 证书。尽管它的功能非常有限,但这只是一个例子。

print OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_TEXT,x509)

但是,我想直接控制 var 中的键(需要将其发送到其他函数),为了做到这一点,我做了以下函数

def parse_asn1_der(derfile):
    from pyasn1_modules import  rfc2437,rfc2459
    from pyasn1.codec.der import decoder
    certType = rfc2459.Certificate(); 
    raw=derfile #the result of open(fname,"rb").read()
    cert,rest = decoder.decode(raw, asn1Spec=certType)
    RSAKEYSDATA=frombits(cert.getComponentByName("tbsCertificate").getComponentByName("subjectPublicKeyInfo").getComponentByName("subjectPublicKey"))
    SignatureCert=frombits(cert.getComponentByName("signatureValue")).encode("hex")
    rsaType=rfc2437.RSAPublicKey();
    rsadata,rsadata_rest = decoder.decode(RSAKEYSDATA, asn1Spec=rsaType)
    print "----"
    print "Certificate Plain Data"
    print "RSA Modulus: %X" %rsadata.getComponentByName("modulus")
    print "RSA Public exponent: %X" %rsadata.getComponentByName("publicExponent")
    print "Signature: %s"%SignatureCert
    return rsadata.getComponentByName("modulus")

希望它可以帮助任何环顾四周的人。

于 2015-11-13T02:57:38.467 回答