简单的DER Cert在python中解析

时间:2013-09-14 22:21:44

标签: python ssl-certificate public-key

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

3 个答案:

答案 0 :(得分:10)

以上答案有些陈旧(截至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要快得多。

答案 1 :(得分:8)

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。

答案 2 :(得分:2)

自从我提出这个问题以来已经有很长一段时间了,但由于观看次数的多少,我想描述一下我是如何设法让它发挥作用的。

通过使用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")

希望它可以帮助任何人四处寻找。