Python socket传输RSA加密数据客户端解密失败方案求助
问题解答
错误原因
- 公私钥不匹配:两端各自生成独立的密钥对,服务端用自己的1024位公钥加密数据,客户端用自己生成的512位私钥解密,两者完全不匹配,直接导致解密失败。
- 解密逻辑错位:客户端的解密代码放在了完整消息接收逻辑之外,既没有去除消息头,也没有反序列化pickle格式的加密内容,传入解密函数的参数本身就是错误的。
修改方案
方案1:连接建立后传输公钥(适合临时通信场景)
非对称加密的核心逻辑是公钥加密、私钥解密,你当前是服务端向客户端发数据,所以客户端保留私钥、将公钥发给服务端加密即可。
服务端修改后代码
import pickle import socket import rsa import json data = { "1630192500000":{"payload":94}, "1630193400000":{"payload":95}, "1630194300000":{"payload":96} } jsondata = json.dumps(data) HEADERSIZE = 10 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((socket.gethostname(), 1243)) s.listen(5) while True: clientsocket, address = s.accept() print(f"Connection from {address} has been established.") # 第一步:接收客户端发来的公钥 full_pubkey = b'' new_pubkey = True pubkey_len = 0 while True: msg = clientsocket.recv(2048) if new_pubkey: pubkey_len = int(msg[:HEADERSIZE]) new_pubkey = False full_pubkey += msg if len(full_pubkey) - HEADERSIZE == pubkey_len: publicKey = pickle.loads(full_pubkey[HEADERSIZE:]) break # 用客户端公钥加密数据 encMessage = rsa.encrypt(jsondata.encode(), publicKey) # 第二步:发送加密后的业务数据 msg = pickle.dumps(encMessage) msg = bytes(f"{len(msg):<{HEADERSIZE}}", 'utf-8') + msg clientsocket.send(msg)
客户端修改后代码
import socket import pickle import rsa HEADERSIZE = 10 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((socket.gethostname(), 1243)) # 客户端生成公私钥对,私钥留着解密用 publicKey, privateKey = rsa.newkeys(1024) # 先把公钥发给服务端 pubkey_bytes = pickle.dumps(publicKey) pubkey_msg = bytes(f"{len(pubkey_bytes):<{HEADERSIZE}}", 'utf-8') + pubkey_bytes s.send(pubkey_msg) while True: # 接收加密的业务数据 full_msg = b'' new_msg = True msglen = 0 while True: msg = s.recv(2048) if new_msg: msglen = int(msg[:HEADERSIZE]) new_msg = False full_msg += msg if len(full_msg)-HEADERSIZE == msglen: enc_data = pickle.loads(full_msg[HEADERSIZE:]) break # 解密输出 decMessage = rsa.decrypt(enc_data, privateKey).decode() print("解密后的字符串: ", decMessage)
方案2:本地存密钥文件(适合固定端通信场景)
你提到的服务端存文件、客户端加载的方式完全可行,安全性更高,不需要每次连接都传输公钥,实现步骤如下:
- 先运行一次密钥生成脚本,生成公钥和私钥文件
import rsa # 生成1024位密钥对 publicKey, privateKey = rsa.newkeys(1024) # 保存公钥,放到服务端运行目录 with open("public.pem", "wb") as f: f.write(publicKey.save_pkcs1("PEM")) # 保存私钥,放到客户端运行目录 with open("private.pem", "wb") as f: f.write(privateKey.save_pkcs1("PEM"))
- 服务端加载公钥加密数据,代码片段如下:
import rsa # 加载公钥 with open("public.pem", "rb") as f: publicKey = rsa.PublicKey.load_pkcs1(f.read()) # 加密逻辑和之前一致 encMessage = rsa.encrypt(jsondata.encode(), publicKey)
- 客户端加载私钥解密数据,代码片段如下:
import rsa # 加载私钥 with open("private.pem", "rb") as f: privateKey = rsa.PrivateKey.load_pkcs1(f.read()) # 解密逻辑和之前一致 decMessage = rsa.decrypt(enc_data, privateKey).decode()
内容的提问来源于stack exchange,提问作者bbartling
相关产品推荐
相关产品推荐

