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

Python中使用密码学底层原语进行非对称公钥验证报错,原因何在?

AttributeError when verifying ECDSA signature: 'bytes' object has no attribute 'verify'

嘿,这个问题我很熟悉,咱们一步步来拆解:

错误原因

你代码里的关键问题出在这一行:

public_key = public_key.public_bytes(encoding=Encoding.DER, format=PublicFormat.SubjectPublicKeyInfo)

原本public_key是**EllipticCurvePublicKey对象**,这个类自带verify()方法。但你用public_bytes()把它转换成了DER格式的字节串,还把结果重新赋值给了同一个变量——这就把原来的公钥对象给覆盖成普通的bytes类型了!而bytes对象根本没有verify()方法,自然会抛出这个AttributeError。

正确的验证方式

有两种解决思路,看你的需求来选:

思路1:保留原始公钥对象(适合本地生成密钥对的场景)

不要覆盖原始的公钥对象,把序列化后的字节串存到另一个变量里:

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat

private_key = ec.generate_private_key(ec.SECP256K1(), default_backend())
# 保留原始公钥对象,用于后续验证
original_public_key = private_key.public_key()
# 序列化公钥为字节串(用于存储或传输)
public_key_bytes = original_public_key.public_bytes(
    encoding=Encoding.DER,
    format=PublicFormat.SubjectPublicKeyInfo
)

message = b'caramel pie'
signature = private_key.sign(message, ec.ECDSA(hashes.SHA256()))
# 使用原始公钥对象执行验证
original_public_key.verify(signature, message, ec.ECDSA(hashes.SHA256()))

思路2:从字节串重新加载公钥(适合公钥是从外部获取的场景)

如果你的公钥已经是字节串形式(比如从文件读取、网络传输过来),需要先把它反序列化为EllipticCurvePublicKey对象,再执行验证:

# 从DER格式的字节串重新加载公钥对象
loaded_public_key = serialization.load_der_public_key(
    public_key_bytes,
    backend=default_backend()
)
# 或者用另一种方式(针对EC密钥的特定加载方法)
loaded_public_key = ec.EllipticCurvePublicKey.from_encoded_point(
    ec.SECP256K1(),
    public_key_bytes
)

# 现在可以正常验证了
loaded_public_key.verify(signature, message, ec.ECDSA(hashes.SHA256()))

额外提示

记住:public_bytes()只是把密钥对象转换成可存储/传输的字节格式,它本身不是密钥对象。验证签名必须用密钥实例对象,而不是序列化后的字节串。

内容的提问来源于stack exchange,提问作者Yordan Иванов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 23:09:05