Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 497
eshizhan Avatar asked Oct 16 '12 09:10

eshizhan


People also ask

How does an x509 certificate work?

509 certificate contains an identity and a public key. It binds an identity -- such as an individual or hostname -- to a public key with a digital signature. The signature is either made by a trusted certificate authority (CA) or is self-signed. Some digital certificates can also be automated.

Does TLS use x509?

509 certificates are digital files that are used for Secure Sockets Layer (SSL) or Transport Layer Security (TLS). An SSL/TLS certificate is one of the most popular types of X. 509 certificates or a type of public-key certificate which uses the X. 509 standard.

What is x509 certificate authentication?

An X. 509 certificate is a digital certificate based on the widely accepted International Telecommunications Union (ITU) X. 509 standard, which defines the format of public key infrastructure (PKI) certificates. They are used to manage identity and security in internet communications and computer networking.

Where is x509 certificate stored?

Certificates stores are kept in the system registry under the keys HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates and HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates. Each user has a MY certificate store which contains his/her personal certificates.


2 Answers

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)
like image 68
SquareRootOfTwentyThree Avatar answered Oct 09 '22 00:10

SquareRootOfTwentyThree


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)
like image 2
earthling Avatar answered Oct 09 '22 00:10

earthling