使用DER格式的X509证书解析python二进制文件以提取公钥是最好的方法。
答案 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")
希望它可以帮助任何人四处寻找。