How do I use a X509 certificate with PyCrypto?
Asked Answered
M

2

24

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)
Mikesell answered 16/10, 2012 at 9:18 Comment(2)
First response in a google search: #10569689Badger
@Badger doesn't work with me, I use certificate, not a public key file.Mikesell
S
39

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)
Submiss answered 16/10, 2012 at 19:14 Comment(5)
As a note, PEM->DER conversion could be done easier using builtin ssl.PEM_cert_to_DER_cert().Juggle
Can you explain how to crypt a string after this step?Allyson
is it still the case in 2016 ?Sikhism
In 2016, one can use pycryptodome, which can read in X.509 certificates directly with importKey.Submiss
This is required for anyone verifying google oauth tokens on their own because their published public keys are x509 certs, googleapis.com/oauth2/v1/certsBinni
D
2

Here's a good example: https://www.dlitz.net/software/pycrypto/api/2.6/Crypto.Cipher.PKCS1_OAEP-module.html

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

# sender side
message = 'To be encrypted'
key = RSA.importKey(open('pubkey.der').read())
cipher = PKCS1_OAEP.new(key)
ciphertext = cipher.encrypt(message)

# receiver side
key = RSA.importKey(open('privkey.der').read())
cipher = PKCS1_OAEP.new(key)
message = cipher.decrypt(ciphertext)
Diseuse answered 9/1, 2017 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.