エラーメッセージ
Malformed base64 encoding
別の表記
- error code: -3 error message: Malformed base64 encoding
`bitcoin-cli` は、メッセージ本文の前に「error code: -3」と「error message:」を出力します。base64 として正しい形式の文字列でも、有効な署名でなければ、エラーではなく `false` が返されます。
Bitcoin Core RPC — verifymessage with a signature that is not base64
このエラーの意味
`verifymessage` は、65 バイトのコンパクト署名を標準の base64 でエンコードしたもの(88 文字、通常は `H`、`I`、`G`、`J` のいずれかで始まる)を想定しています。渡された文字列が有効な base64 ではないため、Core は鍵の復元を試みることさえせず、RPC エラー -3 を返しました。署名自体は正しい可能性があります。誤っているのはテキストのエンコーディングです。
発生する理由
base64 ではなく 16 進数
よくあるアプリケーションやハードウェアウォレットの SDK は、署名を 16 進数(130 文字)で返すことがよくあります。Core はこれを拒否します。
URL やフォームの処理で破損
ときどきフォームのデコードで `+` が空白に変わった場合、`%2B`/`%3D` がエンコードされたまま残っている場合、または Web ライブラリが base64url(`-`、`_`)を生成した場合です。
Ethereum の署名
ときどき`personal_sign` による `0x…` の署名は別の方式(EIP-191 のプレフィックス付き、v の規約も異なる)であり、base64 でもありません。
修正方法
- 1.
16 進数の署名を base64 に変換する
16 進数をデコードして 65 バイトに戻し、改行なしの標準 base64 でエンコードしてください。
bash sig_b64=$(printf '%s' "$SIG_HEX" | xxd -r -p | base64 -w0) # 65 bytes -> 88 base64 characters bitcoin-cli verifymessage "$ADDRESS" "$sig_b64" "$MESSAGE" - 2.
URL エンコードと base64url エンコードを元に戻す
まずパーセントエンコーディングをデコードし、次に base64url をパディング付きの標準 base64 に変換してください。
python import base64, urllib.parse sig = urllib.parse.unquote(sig_from_query) # undo %2B / %2F / %3D sig = base64.b64encode(base64.urlsafe_b64decode(sig + "=" * (-len(sig) % 4))).decode() # base64url -> base64