Как лучше всего проанализировать с помощью python двоичный файл с сертификатом X509 в формате DER для извлечения открытого ключа.
Простой анализ сертификата DER в python
Ответы (3)
Ни встроенный модуль SSL Python, ни 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.
Приведенные выше ответы несколько устарели (по состоянию на 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
.
ValueError: Error parsing asn1crypto.x509.Certificate - tag should have been 16, but 13 was found
Почему это так?
- person Bogota; 17.06.2020
Прошло много времени с тех пор, как я задавал этот вопрос, хотя из-за количества просмотров я хотел бы описать, как мне удалось заставить его работать.
Используя 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")
Надеюсь, это поможет любому, кто смотрит вокруг.
ssl._ssl._test_decode_cert
) и вариантctypes
для сравнения (не рекомендуется) -- в примерах извлекается серийный номер - person jfs   schedule 06.04.2020