Search code examples
pythonopensslrsapycrypto

How do I use a X509 certificate with PyCrypto?


I want to encrypt some data in python with PyCrypto.

However I get an error when using key = RSA.importKey(pubkey):

RSA key format is not supported

The key was generated with:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mycert.key -out mycert.pem

The code is:

def encrypt(data):
    pubkey = open('mycert.pem').read()
    key = RSA.importKey(pubkey)
    cipher = PKCS1_OAEP.new(key)
    return cipher.encrypt(data)

Solution

  • PyCrypto does not support X.509 certificates. You must first extract the public key with the command:

    openssl x509 -inform pem -in mycert.pem -pubkey -noout > publickey.pem
    

    Then, you can use RSA.importKey on publickey.pem.


    If you don't want or cannot use openssl, you can take the PEM X.509 certificate and do it in pure Python like this:

    from Crypto.Util.asn1 import DerSequence
    from Crypto.PublicKey import RSA
    from binascii import a2b_base64
    
    # Convert from PEM to DER
    pem = open("mycert.pem").read()
    lines = pem.replace(" ",'').split()
    der = a2b_base64(''.join(lines[1:-1]))
    
    # Extract subjectPublicKeyInfo field from X.509 certificate (see RFC3280)
    cert = DerSequence()
    cert.decode(der)
    tbsCertificate = DerSequence()
    tbsCertificate.decode(cert[0])
    subjectPublicKeyInfo = tbsCertificate[6]
    
    # Initialize RSA key
    rsa_key = RSA.importKey(subjectPublicKeyInfo)