多次通過的簽名消息的簽名消息驗證失敗
我正在使用 web3 使用以下程式碼驗證簽名消息:
web3.eth.accounts.recover(message, signature);
我正在針對 EtherScan 上公開驗證的簽名列表進行測試 - https://etherscan.io/verifiedSignatures這實際上適用於那裡的絕大多數簽名。
例如,以這個公開驗證的簽名為例,我可以看到控制台輸出
0x65f4667a96bbfd393f39b35b84145f2521bb359c
符合預期並由 EtherScan 驗證web3.eth.accounts.recover("test message", "0x290aa619d5e054c3de8b5f48e2a88e0ce410b2aea2ad3deb5c2ea7e270a10f3d27c85801ad48445a37fc27eecc86bbec92748af5fde22159a8bbe923278ec43a1b")
但是,嘗試對這個公開驗證的簽名執行相同的操作會返回一個輸出結果,這與 etherscan ( )
0x31e7d77287169f0AF8aE63d276441f905A68b7aD
上發布的地址不匹配0x8F5d3Ad9A330009C751D76cAc7D27F929AC059CE
web3.eth.accounts.recover("I have the private key for 0x8f5d3ad9a330009c751d76cac7d27f929ac059ce", "0xa45a8a4d35158f3610a7a8263c048b171fbf6ed9fe31a958e56be73323bf585d67a689dc361226512b04be308ccbe4e93b6c49c2253d2299dd243edd563299e701")
例外似乎是那些 EtherScan 在結果中指示有多次通過的條目。
通過 2 次甚至 3 次驗證簽名是什麼意思,這樣做的原因是什麼?我找不到與此相關的文件
謝謝!
好的,終於能夠弄清楚這一點。我注意到 EtherScan 感謝 Nethereum 提供我碰巧熟悉的模組,所以我查看了
MessageSignerTests
inNethereum.Signer.UnitTests
,似乎差異在於它是否是傳遞給恢復函式的原始消息,或它的散列版本。除此之外,我們還需要考慮是否\x19Ethereum Signed Message:\n<length of message>
應用了 Geth 前綴 ( ) 一次或兩次。這是我能夠推斷出的:
已通過驗證(1)
這是“最簡單”的形式,其中消息應該是字元串形式的文本(連同 Geth 前綴)
web3.eth.accounts.recover(message, signature);
通過驗證(2)
這意味著簽名的消息經過雜湊處理,隨後在沒有Geth 前綴的情況下簽名,因此為了恢復地址,我們還需要將
preFixed
參數設置為true
,否則web3.eth.accounts.recover
會附加 Geth 前綴並且驗證將失敗。let hashedMessage = web3.utils.keccak256(message); web3.eth.accounts.recover(hashedMessage, signature, true);
通過驗證(3)
這意味著消息經過雜湊處理和簽名,但與前面的範例不同,它使用Geth 前綴,因此要恢復我們需要
let hashedMessage = web3.utils.keccak256(message); web3.eth.accounts.recover(hashedMessage, signature);