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 バイトにパディングした空の署名などです。
壊れたバイト列
ときどきエンコーディングの往復変換(16 進 ↔ base64、文字列 ↔ バイト列)で壊れた署名は、長さが 65 バイトのままでも、曲線上の点を表さなくなっていることがあります。
別の方式の署名
ときどきたまたま 64 バイトである P-256(WebAuthn/パスキー)や Ed25519 の署名に、v のバイトを付け足したものです。これは Ethereum の署名ではありません。
修正方法
- 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