鍵の「形」を盗む泥棒たち:EIP-1271が抱える意外な盲点
みなさん、こんにちは!ITの世界へようこそ。
普段、スマートフォンの認証やWebサイトへのログインで「署名」という言葉を耳にすることはありませんか?
今日は、そんな「デジタルな署名」の世界で、いま最も注目されている「EIP-1271」という仕組みの裏側に潜む、ちょっと怖い「なりすまし」の落とし穴についてお話しします。難しそうに聞こえるかもしれませんが、身近な「家の鍵」に例えながら、一緒に紐解いていきましょう!
—
1. 署名って、実は「身分証明書」のことなんです
私たちが自分のウォレット(暗号資産の財布)から何かを送る時、必ず「秘密鍵」という電子的なハンコを押します。これを「署名」と呼びます。
しかし、最近増えている「スマートコントラクトウォレット」という特殊な財布は、人間ではなく「プログラム」で動いています。このプログラムが「これは私が押したハンコですよ」と証明するために使われるのが EIP-1271 という規格です。
例えるなら、「この屋敷の主人は、AI執事が発行した証明書を持ってくるはずだ。その証明書を執事に見せて確認させれば間違いはない」という取り決めのようなものです。
2. なぜ「なりすまし」が起きるのか?(再帰呼び出しの罠)
さて、ここからが本題です。もし、この「AI執事(スマートコントラクト)」が、うっかり騙されやすい性格だったらどうでしょう?
攻撃者は、わざと「自分自身を呼び出すような複雑な命令」を仕込みます。これを専門用語で「再帰呼び出し」と呼びます。
泥棒の手口:鏡合わせのトリック
泥棒は、家の鍵(署名)を盗むのではなく、「鍵を確認するルールそのもの」を書き換えてしまいます。
1. 攻撃者は、「私の署名は正しいですよね?」と執事に聞きます。
2. 執事が確認しようとした瞬間、攻撃者は「いや、もう一度最初から確認して!」と複雑な命令を送り、執事をパニック(無限ループ)に陥らせます。
3. その隙に、執事が「はい、正しいです!」と言わざるを得ない状況を作り出し、堂々と屋敷(ウォレット)に侵入するのです。
これが、EIP-1271の検証ロジックが甘いときに発生する「なりすましリスク」の正体です。
—
3. 守るための第一歩:コードで見る「防御の仕組み」
では、どうすればこの泥棒を防げるのでしょうか?
ポイントは、「誰から確認の依頼が来ても、必ず決まった手順で冷静にチェックすること」です。
以下は、安全な検証を行うための基本的な考え方を示したコード例です。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SecureWallet {
// 署名の有効性を確認するメインの関数
function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) {
// 1. まず、署名が正しい形式かチェック(ここで無駄な計算をさせない)
require(_signature.length == 65, "署名の長さが不正です!");
// 2. 署名者(持ち主)が本当に本人か確認
address signer = recoverSigner(_hash, _signature);
// 3. 本人であれば、特定の「魔法の合言葉(MagicValue)」を返す
if (signer == owner) {
// 0x1626ba7e は「この署名は正しいですよ」と伝えるための合言葉
return 0x1626ba7e;
}
// 失敗した場合は無効であることを伝える
return 0xffffffff;
}
}
ポイント解説
0x1626ba7e: これが「EIP-1271の合言葉」です。これを返さないと、世の中の多くのシステムは「この署名は偽物だ」と判断します。require: これが「門番」です。怪しい入力が来たら、すぐに門を閉じて(処理を中断して)泥棒を追い返します。
—
4. セキュリティリサーチャーからのアドバイス
新人開発者の皆さんに、これだけは覚えておいてほしいことがあります。
「プログラムは、あなたが書いた通りに動くのではなく、あなたが書かなかった例外の時ほど、予期せぬ動きをする」
特にブロックチェーンの世界では、一度公開したルールを後から直すのは非常に困難です。「まあ大丈夫だろう」という油断が、数億円規模の被害を生むこともあります。
私たちができること:
1. 複雑にしない: 検証ロジックは可能な限りシンプルに保ちましょう。
2. 外部を信じない: 他のコントラクトからの呼び出しには、必ず「これは本当に許可された相手か?」というチェックを挟んでください。
3. テストを徹底する: 泥棒になったつもりで、「もし変なデータが来たらどうなる?」という意地悪なテストをたくさん書きましょう。
セキュリティは、一度完成して終わりではありません。家の鍵を毎日確認するように、少しずつ知識をアップデートしていきましょうね。
また次回の記事で、より深い「防御の極意」についてお話ししましょう。それでは、安全な開発ライフを!
コメント