Web3js

多次通過的簽名消息的簽名消息驗證失敗

  • December 28, 2018

我正在使用 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 提供我碰巧熟悉的模組,所以我查看了MessageSignerTestsin Nethereum.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);

引用自:https://ethereum.stackexchange.com/questions/64667