Can't pickle an RSA key to send over a socket
<p>I have a list with a public key and a username that I want to send over a socket.</p>

<p>I found 
<a href="http://stackoverflow.com/questions/24423162/how-to-send-an-array-over-a-socket-in-python">how to send an array over a socket in python</a> but using pickling won't work either.</p>

<p>My code:</p>

<pre><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)
</code></pre>

<p>The error in the console says</p>

<pre><code>     dataSend = pickle.dumps(dataToSend)
_pickle.PicklingError: Can't pickle &lt;class '_cffi_backend.CDataGCP'&gt;: attribute lookup CDataGCP on _cffi_backend failed
</code></pre>

<p>The key was generated with the <a href="https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/" rel="nofollow"><code>cryptography</code> library</a>.</p>

<p>You are trying to send a <a href="https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey" rel="nofollow"><code>RSAPublicKey</code> instance</a>, 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.</p>

<p>You'll need to pick a <a href="https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#key-serialization" rel="nofollow"><em>key serialization format</em></a> to send it instead. You could convert to PEM, for example:</p>

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

<p>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 <a href="https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#key-loading" rel="nofollow">load the key</a> from that string again.</p>

<p>Note that the above uses <strong>no encryption whatsoever</strong>. 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.</p>

python sockets python-3.x pickle