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)
|