Kalessar
Kalessar

Reputation: 293

Python - Pycrypto - Sending encrypted data over network

I am trying to get 2 programs to share encrypted data over a network using public keys, but I am stuck with a difficult problem : the information that is shared (the keys and/or the encrypted data) seems to get modified. I am hoping to keep the encrypted data format as well as the format of the keys as simple as possible in order to allow compatibility with other languages. To break down the problem, I have created 2 programs : Keyreceive and Keysend. They execute in this order :

  1. Keyreceive starts up and waits to receive the encrypted data
  2. Keysend starts up and generates an RSA key, saving the exported private key to a file
  3. Keysend encrypts a piece of data and sends it to Keyreceive over the network
  4. Keyreceive imports the private key from the same file, and uses it to decrypt the encrypted data
  5. Keysend also decrypts the encrypted data to verify the result

Keysend.py

import socket
import os
from Crypto.PublicKey import RSA
from Crypto import Random

rng = Random.new().read
RSAkey = RSA.generate(1024, rng) 

privatekey = RSAkey
publickey = RSAkey.publickey()
print(privatekey.exportKey()) #export under the 'PEM' format (I think)
print(publickey.exportKey())

file = open("Keys.txt", "w")
file.write(privatekey.exportKey()) #save exported private key
file.close()

data = "hello world"
enc_data = publickey.encrypt(data, 16) #encrypt message with public key
print(str(enc_data))

host = "localhost"
port = 12800
connexion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion.connect((host, port))
connexion.send(str(enc_data)) # send encrypted data, this appears to be the source of the problem

dec_data = RSAkey.decrypt(enc_data) # test decryption
print(dec_data)

os.system("pause")

Keyreceive.py

import socket
import os
from Crypto.PublicKey import RSA
from Crypto import Random

host = ''
port = 12800

connexion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion.bind((host, port))
connexion.listen(5)
clientconnexion, connexioninfo = connexion.accept()
enc_data = clientconnexion.recv(1024) # receive encrypted data
print(enc_data)

file = open("Keys.txt", "r")
privatestr = file.read() # retrieve exported private key from file
file.close()
print(privatestr)

privatekey = RSA.importKey(privatestr) # import private key
data = privatekey.decrypt(enc_data) # decrypt sent encrypted data
print(data)

os.system("pause")

After both files have finished decrypting the encrypted data, Keysender outputs the original message : "hello world", whereas Keyreceiver outputs gibberish. If there is "hidden" information in the encrypted data and key formats, would there be some way of writing them in a "pure" text format?

Upvotes: 3

Views: 7688

Answers (1)

Jeremy Roman
Jeremy Roman

Reputation: 16345

You're right about which line is the source of the problem.

connexion.send(str(enc_data))

enc_data here is a tuple, the first (and in fact only) element of which is a string containing the actual ciphertext. When you are calling str on it, you're getting Python's attempt to convert the tuple to a string, which is not what you want. If you change it to this:

connexion.send(enc_data[0])

then it should do what you want.

Upvotes: 5

Related Questions