Python - Parse X509 Certificate
#!/usr/bin/env python # -*- coding: utf-8 -*- from OpenSSL.crypto import (load_certificate, dump_privatekey, dump_certificate, X509, X509Name, PKey) from OpenSSL.crypto import (TYPE_DSA, TYPE_RSA, FILETYPE_PEM, FILETYPE_ASN1 ) from Crypto.Util.asn1 import (DerSequence, DerObject) from datetime import datetime import textwrap def format_subject_issuer(x509name): items = [] for item in x509name.get_components(): items.append('%s=%s' % (item[0], item[1]) ) return ", ".join(items); def format_split_bytes(aa): bb = aa[1:] if len(aa)%2==1 else aa #force even num bytes, remove leading 0 if necessary out = format(':'.join(s.encode('hex').lower() for s in bb.decode('hex'))) return out def format_split_int(serial_number): aa = "0%x" % serial_number #add leading 0 return format_split_bytes(aa) def format_asn1_date(d): return datetime.strptime(d.decode('ascii'), '%Y%m%d%H%M%SZ').strftime("%Y-%m-%d %H:%M:%S GMT") def get_signature_bytes(x509): der = DerSequence() der.decode(dump_certificate(FILETYPE_ASN1, x509)) der_tbs = der[0] der_algo = der[1] der_sig = der[2] der_sig_in = DerObject() der_sig_in.decode(der_sig) sig=der_sig_in.payload[1:] #skip leading zeros return sig.encode('hex') def get_modulus_and_exponent(x509): if x509.get_pubkey().type()==TYPE_RSA: pub_der = DerSequence() pub_der.decode(dump_privatekey(FILETYPE_ASN1, x509.get_pubkey())) modulus = "%s:%s" % ( format_split_int(pub_der._seq[0]), format_split_int(pub_der._seq[1]) ) exponent = pub_der._seq[2] return [ modulus, exponent ] return '' def parse_cert(cert_file): with open(cert_file, 'rb+') as f: cert_pem = f.read() f.close() x509 = load_certificate(FILETYPE_PEM, cert_pem) keytype = x509.get_pubkey().type() keytype_list = {TYPE_RSA:'rsaEncryption', TYPE_DSA:'dsaEncryption', 408:'id-ecPublicKey'} key_type_str = keytype_list[keytype] if keytype in keytype_list else 'other' pkey_lines=[] pkey_lines.append(" Public Key Algorithm: %s" % key_type_str) pkey_lines.append(" Public-Key: (%s bit)" % x509.get_pubkey().bits()) if x509.get_pubkey().type()==TYPE_RSA: modulus, exponent = get_modulus_and_exponent(x509) formatted_modulus = "\n ".join(textwrap.wrap(modulus, 45)) pkey_lines.append(" Modulus:") pkey_lines.append(" %s" % formatted_modulus) pkey_lines.append(" Exponent %d (0x%x)" % (exponent,exponent)) sig_formatted = "\n ".join( textwrap.wrap(format_split_bytes(get_signature_bytes(x509)), 54) ) print("Certificate:") print(" Data:") print(" Version: %s (0x%x)" % (int(x509.get_version()+1), x509.get_version()) ) print(" Serial Number:") print(" %s" % format_split_int(x509.get_serial_number())) print(" Signature Algorithm: %s" % x509.get_signature_algorithm()) print(" Issuer: %s" % format_subject_issuer( x509.get_issuer() ) ) print(" Validity") print(" Not Before: %s" % format_asn1_date(x509.get_notBefore())) print(" Not After : %s" % format_asn1_date(x509.get_notAfter())) print(" Subject: %s" % format_subject_issuer( x509.get_subject() ) ) print(" Subject Public Key Info:") print("\n".join(pkey_lines)) print(" X509v3 extensions:") for i in xrange(x509.get_extension_count()): critical = 'critical' if x509.get_extension(i).get_critical() else '' print(" x509v3 %s: %s" % (x509.get_extension(i).get_short_name(), critical) ) print(" %s" % x509.get_extension(i).__str__() ) print(" Signature Algorithm: %s" % x509.get_signature_algorithm() ) print(" %s" % sig_formatted) print(" Thumbprint MD5: %s" % x509.digest('md5')) print(" Thumbprint SHA1: %s" % x509.digest('sha1')) print(" Thumbprint SHA256: %s" % x509.digest('sha256')) if __name__ == "__main__": import sys import os os.chdir(sys.path[0]) parse_cert("cert.pem"); sys.exit(0)
code snippets are licensed under Creative Commons CC-By-SA 3.0 (unless otherwise specified)