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

PyCryptodome实现RSA签名验证始终返回True问题求助

搞定你的RSA验证总是返回True的问题

嘿,我看了你的代码,发现两个关键问题导致验证函数不管传啥都返回True,咱们一步步来解决:

1. 你搞反了密钥的用途!

RSA签名的核心逻辑是私钥签名,公钥验证——私钥用来生成只有对应公钥能验证的专属签名,公钥只能做验证不能签名。但你的代码里,sign和verify都用了同一个keys.txt里的密钥,如果这个文件存的是私钥,那用私钥去做验证时,PyCryptodome的PKCS1_v1_5.verify会出现未定义的异常行为,直接跳过验证返回“成功”,这就是为啥不管传什么签名都返回True。

2. 测试用例的签名类型不对(但被第一个问题掩盖了)

你的sign函数返回的签名是字节对象,但测试用例里传的是字符串:

verify(["this will return"," true whatever I enter"], keys)

正常来说,字符串和字节类型不匹配会触发TypeError,被你的except块捕获后返回False,但因为第一个问题的存在,这个异常根本没触发,反而让验证“通过”了。


修复后的完整代码

第一步:先生成并分开保存私钥和公钥

先运行一次这段代码生成密钥对:

from Crypto.PublicKey import RSA

# 生成2048位RSA密钥对
key_pair = RSA.generate(2048)
# 保存私钥(仅用于签名)
with open("private_key.pem", "wb") as f:
    f.write(key_pair.exportKey())
# 保存公钥(仅用于验证)
with open("public_key.pem", "wb") as f:
    f.write(key_pair.publickey().exportKey())

修正后的RSA_Handler.py

from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
import pickle

def sign(data, private_key_data):
    key = RSA.importKey(private_key_data)
    # 序列化数据并生成SHA256哈希
    serialized_data = pickle.dumps(data)
    hash_obj = SHA256.new(serialized_data)
    # 用私钥生成签名
    signature = PKCS1_v1_5.new(key).sign(hash_obj)
    return [data, signature]

def verify(signed_data, public_key_data):
    data = signed_data[0]
    signature = signed_data[1]
    key = RSA.importKey(public_key_data)
    # 重新生成待验证数据的哈希
    serialized_data = pickle.dumps(data)
    hash_obj = SHA256.new(serialized_data)
    try:
        # 用公钥验证签名合法性
        PKCS1_v1_5.new(key).verify(hash_obj, signature)
        return True
    except (ValueError, TypeError):
        # 验证失败时捕获异常,返回False
        return False

修正后的test01.py

from RSA_Handler import *

# 读取私钥用于签名
with open("private_key.pem", "rb") as rb:
    private_key = rb.read()
# 读取公钥用于验证
with open("public_key.pem", "rb") as rb:
    public_key = rb.read()

# 正常场景:合法签名验证
signed_data = sign("hello", private_key)
print("合法签名验证结果:", verify(signed_data, public_key))  # 输出True

# 异常场景:伪造数据+随机签名
invalid_result = verify(["fake data", b"random_signature_bytes"], public_key)
print("非法签名验证结果:", invalid_result)  # 输出False

额外提醒:别用pickle做序列化!

pickle是非常不安全的,如果攻击者能控制你要验证的数据,他们可以构造恶意的pickle payload,在你调用pickle.dumps()的时候执行任意代码。建议换成更安全的方式,比如json.dumps()(如果数据是JSON可序列化的),或者用固定格式的字节编码(比如把字符串转成UTF-8字节)。

内容的提问来源于stack exchange,提问作者CodEdo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:37:38