Encrypt a message with RSA in python
May 5, 2008 6 Comments
Update
As an aside as I’m going through old posts: There’s a lot more that needs to be done to make this “good”. For one, the message shouldn’t be applied directly to RSA – rather, a hash should be used…. and for another, there’s no auth, and for another, the unsafe pickle might be code execution… below is just a toy for basic usage
For some people in my class this was easy, and others it was difficult. Some people have spent a good 40 hours on this, so I thought I’d post some code to help out. There isn’t much documentation on the crypto modules.
server.py
#!/usr/bin/env python from Crypto.Hash import MD5 from Crypto.PublicKey import RSA from Crypto.Util import randpool import pickle import socket import sys #generate the RSA key blah = randpool.RandomPool() RSAKey = RSA.generate(512, blah.get_bytes) RSAPubKey = RSAKey.publickey() #listen for a connection host = '' port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((host,port)) s.listen(1) print "Server is running on port %d; press Ctrl-C to terminate." % port while 1: clientsock, clientaddr = s.accept() print "got connection from ", clientsock.getpeername() #send the public key over clientsock.send(pickle.dumps(RSAPubKey)) rcstring = '' while 1: buf = clientsock.recv(1024) rcstring += buf if not len(buf): break clientsock.close() #done with the network stuff, at least for this connection #encmessage is the cipher text encmessage = pickle.loads(rcstring) print RSAKey.decrypt(encmessage)
client.py
#!/usr/bin/env python from Crypto.Hash import MD5 from Crypto.PublicKey import RSA from Crypto.Util import randpool import pickle import socket host = 'localhost' port = 12345 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) #this should loop around until a delimeter is read #or something similar rcstring = s.recv(2048) #this object is of type RSAobj_c, which only has public key #encryption is possible, but not decryption publickey = pickle.loads(rcstring) print publickey #encrypt the top secret data secretText = publickey.encrypt("Hello, this is Rich.", 32) s.sendall(pickle.dumps(secretText)) s.close()
Hey, very nice guide! Thank you for taking the time to share. Python is great :D
Thanks, for me was difficult too! :D
As an aside as I’m going through old posts: There’s a lot more that needs to be done to make this “good”. For one, the message shouldn’t be applied directly to RSA – rather, a hash should be used…. and for another, there’s no auth… above is just a toy
i am new to python programming , i want to ask
how to i able to modify the code so that , the server send the encrypted message, and the client decrypt and print the message?
In a good crypto scheme, RSA would most likely be used to exchange a unique key that’s used for a symmetric cipher – then the client and server use that to send real messages. To abstract this a bit, you could probably use the python SSL libraries.
In a bad crypto scheme like above, just reverse the sides. The client would need to give the server a public key to encrypt with, then decrypt with its private key.
RSA.generate(512, blah.get_bytes)
is not going to work anymore , you need to have a length of at least 1024