Generating Cryptography Keys in Python
March 27, 2012 at 09:18 AM | categories: Python, SSL, Howto | View CommentsPyOpenSSL may seem like the obvious option when working with cryptography keys in Python but i have found it to have some short coming such as the inability to save both the public and private key in a key pair.
M2Crypto on the other hand allows you to save both keys to either a file or store it in a buffer which is useful if you want to save the keys say to a database.
Examples of M2Crypto usage are hard to come by, hope my few examples will save someone else the effort of searching.
Examples
Generate Key pair in memory
import os from M2Crypto import Rand, RSA, BIO KEY_LENGTH = 1024 def blank_callback(): "Replace the default dashes" return # Random seed Rand.rand_seed (os.urandom (KEY_LENGTH)) # Generate key pair key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback) # Create memory buffers pri_mem = BIO.MemoryBuffer() pub_mem = BIO.MemoryBuffer() # Save keys to buffers key.save_key_bio(pri_mem, None) key.save_pub_key_bio(pub_mem) # Get keys public_key = pub_mem.getvalue() private_key = pri_mem.getvalue()
Generate Key pair to file
from M2Crypto import Rand, RSA KEY_LENGTH = 1024 def blank_callback(): "Replace the default dashes" return # Random seed Rand.rand_seed (os.urandom (KEY_LENGTH)) # Generate key pair key = RSA.gen_key (KEY_LENGTH, 65537, blank_callback) # Non encrypted key key.save_key('user-private.pem', None) # Use a pass phrase to encrypt key #key.save_key('user-private.pem') key.save_pub_key('user-public.pem')
Encrypt a text using a public key
from M2Crypto import RSA # Load the recipients public key writer = RSA.load_pub_key('user-public.pem') # Encrypt the message cipher = writer.public_encrypt('Secret message', RSA.pkcs1_oaep_padding) # store the encrypted message msg = cipher.encode('base64')
Signing a message
from M2Crypto import RSA, EVP # load private key mykey = RSA.load_key('user-private.pem') # generate a digest thedigest = EVP.MessageDigest('sha1') # update the cipher text thedigest.update(cipher) #sign the message signature = mykey.sign_rsassa_pss(thedigest.digest()) # display the signature print signature.encode('base64')
Decrypt a message
from M2Crypto import RSA mykey = RSA.load_key ('user-private.pem') plaintext = mykey.private_decrypt(cipher, RSA.pkcs1_oaep_padding)
Verify a message
from M2Crypto import RSA, EVP senderkey = RSA.load_pub_key('sender-public.pem') thedigest = EVP.MessageDigest('sha1') thedigest.update(cipher) senderkey.verify_rsassa_pss(thedigest.digest(), signature) == 1
References
blog comments powered by Disqus