Python - Pycrypto - 通过网络发送加密数据

3 投票
1 回答
7620 浏览
提问于 2025-04-16 22:35

我正在尝试让两个程序通过网络共享加密数据,使用的是公钥,但遇到了一个棘手的问题:共享的信息(包括密钥和/或加密数据)似乎被修改了。我希望能把加密数据和密钥的格式保持得尽可能简单,以便与其他语言兼容。

为了分析这个问题,我创建了两个程序:Keyreceive 和 Keysend。

  1. 首先,Keyreceive 启动并等待接收加密数据。
  2. 接着,Keysend 启动并生成一个 RSA 密钥,把导出的私钥保存到一个文件中。
  3. 然后,Keysend 加密一段数据,并通过网络发送给 Keyreceive。
  4. Keyreceive 从同一个文件中导入私钥,并用它来解密加密的数据。
  5. 最后,Keysend 也解密加密的数据,以验证结果。

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

在两个文件完成解密后,Keysend 输出了原始消息:“hello world”,而 Keyreceive 却输出了一堆乱码。如果加密数据和密钥格式中有“隐藏”的信息,是否有办法将它们以“纯”文本格式写出来呢?

1 个回答

5

你说得对,问题出在哪一行。

connexion.send(str(enc_data))

enc_data在这里是一个元组,它的第一个(也是唯一的)元素是一个包含实际密文的字符串。当你对它使用str时,Python会试图把这个元组转换成字符串,这并不是你想要的效果。如果你把它改成这样:

connexion.send(enc_data[0])

那么它应该就能达到你想要的效果。

撰写回答