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

PyCryptodome中DSA-DSS/ECDSA签名验证返回False问题求助

嘿,这个问题我太熟悉了!你踩的是PyCryptodome库中哈希对象的一个常见特性坑——当你调用签名方法时,哈希对象的内部数据会被读取消耗,导致后续再用同一个对象验证时,相当于在验证一个空的哈希值,自然返回False。不管是DSA-DSS还是ECDSA场景,这个逻辑都是一致的。

问题核心原因

SHA256.new()创建的哈希对象是一次性的读写对象:当signer.sign(hash_obj)执行时,方法会读取哈希对象的全部内容用于生成签名,此时哈希对象的内部指针会移动到末尾,后续再调用verify()时,读取到的哈希值是空的,和签名时的哈希值不匹配,验证失败。

两种修复方案

方案1:验证时重新生成哈希对象

最直接的方式是针对原消息重新创建一个全新的哈希对象,确保验证用的哈希值和签名时完全一致。

修改后的完整代码:

from Crypto.PublicKey import DSA
from Crypto.Signature import DSS
from Crypto.Hash import SHA256

# 签名流程
key = DSA.generate(2048)
publickey = key.publickey()
message = b"Hello"
hash_obj = SHA256.new(message)
signer = DSS.new(key, 'fips-186-3')
signature = signer.sign(hash_obj)

# 验证流程(重新生成哈希对象)
verify_hash = SHA256.new(message)  # 关键:用原消息重新生成哈希
verifier = DSS.new(publickey, 'fips-186-3')
try:
    verifier.verify(verify_hash, signature)
    print("DSA签名验证成功!")
except ValueError:
    print("DSA签名验证失败!")

方案2:签名前复制哈希对象

如果不想重新生成哈希对象,可以在签名前先复制一份哈希对象的副本,用副本去执行签名操作,保留原哈希对象用于验证。PyCryptodome的哈希对象支持copy()方法:

from Crypto.PublicKey import DSA
from Crypto.Signature import DSS
from Crypto.Hash import SHA256

key = DSA.generate(2048)
publickey = key.publickey()
message = b"Hello"
hash_obj = SHA256.new(message)
hash_copy = hash_obj.copy()  # 复制哈希对象副本

# 用副本签名
signer = DSS.new(key, 'fips-186-3')
signature = signer.sign(hash_copy)

# 用原哈希对象验证
verifier = DSS.new(publickey, 'fips-186-3')
try:
    verifier.verify(hash_obj, signature)
    print("DSA签名验证成功!")
except ValueError:
    print("DSA签名验证失败!")
ECDSA场景适配

ECDSA的修复逻辑完全一致,只需要替换对应的密钥和签名模块即可:

from Crypto.PublicKey import ECC
from Crypto.Signature import ecdsa
from Crypto.Hash import SHA256

# 签名流程
key = ECC.generate(curve='P-256')
publickey = key.public_key()
message = b"Hello"
hash_obj = SHA256.new(message)
signer = ecdsa.new(key, 'fips-186-3')
signature = signer.sign(hash_obj)

# 验证流程(重新生成哈希对象)
verify_hash = SHA256.new(message)
verifier = ecdsa.new(publickey, 'fips-186-3')
try:
    verifier.verify(verify_hash, signature)
    print("ECDSA签名验证成功!")
except ValueError:
    print("ECDSA签名验证失败!")

内容的提问来源于stack exchange,提问作者Günel Resulova

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:10:35