0

I have a list with a public key and a username that I want to send over a socket.

I found how to send an array over a socket in python but using pickling won't work either.

My code:

private_key = generateRSA()
public_key = private_key.public_key()
host = ''
port = 8000
username = sys.argv[1]
mySocket = socket.socket()
mySocket.connect((host, port))
dataToSend = [public_key, username.encode()]
dataSend = pickle.dumps(dataToSend)
mySocket.send(dataSend)

The error in the console says

     dataSend = pickle.dumps(dataToSend)
_pickle.PicklingError: Can't pickle <class '_cffi_backend.CDataGCP'>: attribute lookup CDataGCP on _cffi_backend failed

The key was generated with the cryptography library.

Community
  • 1
  • 1
Amanda_Panda
  • 1,156
  • 4
  • 26
  • 68
  • 2
    Your question should be about why you can't pickle a CFFI object. The *reason* you are pickling is because you want to send an arbitrary object over a socket as data, but your problem lies with a specific type of object that can't easily be pickled. – Martijn Pieters Sep 04 '16 at 21:24
  • Can you tell us what project provides the `generateRSA()` function? Then we can help you produce data for the private key; it is an object right now that can't easily be sent, not a string, for example. – Martijn Pieters Sep 04 '16 at 21:25
  • 1
    That's the Python cryptography library. https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/ – Amanda_Panda Sep 04 '16 at 21:33
  • What are you planning to do with the data on the other side of the socket, @Amanda_Panda? Do you actually need the public key *object*, or just a string representation? – dannysauer Sep 04 '16 at 21:43
  • The public key is needed for encryption. I guess I don't really need the object per se then. – Amanda_Panda Sep 04 '16 at 21:43

1 Answers1

0

You are trying to send a RSAPublicKey instance, but this is a data structure managed by SSL, not Python. Because you interact with it through a CFFI proxy, you can't pickle one of these.

You'll need to pick a key serialization format to send it instead. You could convert to PEM, for example:

from cryptography.hazmat.primitives import serialization
pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)

The above would export your key to a string value you could then convert to bytes and send over the socket directly. The other side would load the key from that string again.

Note that the above uses no encryption whatsoever. Anyone intercepting the traffic over that socket would be able to read your public key. That may or may not be a problem for your application.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343