Python - Pycrypto - Sending encrypted data over network
Question: 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?


Answer: 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.

