Encrypt a message with RSA in python

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()

6 Responses to Encrypt a message with RSA in python

  1. Brad Wolfe says:

    Hey, very nice guide! Thank you for taking the time to share. Python is great :D

  2. lArA says:

    Thanks, for me was difficult too! :D

  3. 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

  4. TKN says:

    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.

  5. alexparij says:

    RSA.generate(512, blah.get_bytes)
    is not going to work anymore , you need to have a length of at least 1024

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s