You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:本地存密钥文件(适合固定端通信场景)

你提到的服务端存文件、客户端加载的方式完全可行,安全性更高,不需要每次连接都传输公钥,实现步骤如下:

  1. 先运行一次密钥生成脚本,生成公钥和私钥文件
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"))
  1. 服务端加载公钥加密数据,代码片段如下:
import rsa
# 加载公钥
with open("public.pem", "rb") as f:
    publicKey = rsa.PublicKey.load_pkcs1(f.read())
# 加密逻辑和之前一致
encMessage = rsa.encrypt(jsondata.encode(), publicKey)
  1. 客户端加载私钥解密数据,代码片段如下:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 16:15:02