web3.py / eth-account / eth-keys (Python)Web3 钱包与签名
错误信息
eth_keys.exceptions.BadSignature: Invalid signature
也可能输出为
- BadSignature: Invalid signature
web3.py / eth-account / eth-keys (Python) — BadSignature from public-key recovery
含义
签名长度正确,但其中的值不构成任何有效的 secp256k1 签名,因此无法恢复出公钥:r 或 s 为零或不小于曲线的阶,或者 r 不是曲线上某个点的 x 坐标。这与用错误密钥生成的签名不同——那样的签名会恢复出另一个地址,而不会抛出任何异常。BadSignature 表示这些字节根本不是签名。
原因
全零值或默认值
常见全零的测试数据、数据库列的默认值,或者被客户端填充到 65 字节的空签名。
字节已损坏
偶见在编码往返转换(十六进制 ↔ base64、字符串 ↔ 字节)中损坏的签名,长度可能仍是 65 字节,但已不再对应曲线上的点。
其他签名方案的签名
偶见恰好为 64 字节、又补上了一个 v 字节的 P-256(WebAuthn/通行密钥)或 Ed25519 签名。它不是以太坊签名。
修复方法
- 1.
按被拒绝的签名处理
把 BadSignature 与长度错误、取值错误一起捕获,并拒绝该请求;不要换用其他 v 值重试。
python from eth_keys.exceptions import BadSignature from eth_utils.exceptions import ValidationError def recover_or_none(message, signature) -> str | None: try: return Account.recover_message(message, signature=signature) except (BadSignature, ValidationError, ValueError): return None # reject the request: the signature is malformed