How do I use a X509 certificate with PyCrypto?

eshizhan picture eshizhan · Oct 16, 2012 · Viewed 30.1k times · Source

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)

Answer

SquareRootOfTwentyThree picture SquareRootOfTwentyThree · Oct 16, 2012

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)