Private-Key

乙太坊簽名驗證不匹配

  • May 23, 2017

我想要實現的是簽署一條消息,然後驗證簽名是否由相同的地址驗證。

合約呼叫 ecrecover 方法來驗證地址

contract MyAuth {      
   function verify( bytes32 hash, uint8 v, bytes32 r, bytes32 s) 
       constant returns(address returnAddress) {
       returnAddress = ecrecover(hash, v, r, s);
   }
}

Java 腳本程式碼

var cMyAuthAddress="0x09343c5EBB988315E117E1Cd6EE501AF02412cFB"; // Contract address

var cMyAuthABI="<ABI data>"; // Contract ABI
var cDeployed=web3.eth.contract(JSON.parse(cMyAuthABI)).at(cMyAuthAddress);

var msg = web3.sha3('This my test data');

console.log('Message Hash: '+ msg); // Generated message hash
console.log("Account Used to Sign: "+ web3.eth.accounts[0]);
var state=web3.personal.unlockAccount(web3.eth.accounts[0], '<account password>', 1000); // Unlocking the account to perform the operation
console.log('Account State: '+ state);

var signature = web3.eth.sign(web3.eth.accounts[0], msg); // Signing the messge

console.log('Signature: '+ signature);

var r = signature.slice(0, 66)
var s = '0x' + signature.slice(66, 130)
var v = '0x' + signature.slice(130, 132)
v = web3.toDecimal(v);

console.log("V: "+ v);
console.log("R: "+ r);
console.log("S: "+ s);

if(v<27 || v>28){
   v+=27;
   console.log("Updated V: "+ v);
}

var finalAddress=cDeployed.verify.call(msg,v,r,s)

console.log("Final Address: "+ finalAddress);

輸出

資訊散:0x1c6f4ab842fb95857783a0177eafb0133b3a626c89877a8bf4e2d07987aa1422

賬戶用於簽名:0x890bd380e472df5b8bab22075c6a5d4f0b84415c

帳戶狀態:真正的

簽名:0xb8b01f46f147bd5e8f84343719ca7492164f80af5f60370c433e2e096ae52fec76d2bbe0e454b2a07e4100e8463d98286ec6e849cbcf6e24f66f7d579fc8654f1c

五:28

R:0xb8b01f46f147bd5e8f84343719ca7492164f80af5f60370c433e2e096ae52fec

S:0x76d2bbe0e454b2a07e4100e8463d98286ec6e849cbcf6e24f66f7d579fc8654f

十進制五:28

最終地址:0x0609b9fae476d8b844716e3a0a6a3b5b7a5a2cdf

您可以清楚地看到列出的最終地址與用於簽署消息的地址不匹配。

注意:我正在我的私有區塊鏈上嘗試這個。

問題:需要更正哪個步驟才能達到預期的結果(即最終地址應與在這種情況下用於簽名的帳戶地址匹配,即 0x890bd380e472df5b8bab22075c6a5d4f0b84415c)?

嘗試將 ethereumjs-util 與 baove 生成​​的簽名值一起使用,但結果相同。

 var ethUtils = require('ethereumjs-util'); 
 let tSig = ethUtils.fromRpcSig(signature);
 let pubKey = ethUtils.ecrecover(
   ethUtils.sha3("This my test data"),
   tSig.v,
   tSig.r,
   tSig.s);
 let foundAddr = '0x' + ethUtils.pubToAddress(pubKey).toString('hex');
 console.log("Final Address 2: "+ finalAddress);

輸出為最終地址2:0x0609b9fae476d8b844716e3a0a6a3b5b7a5a2cdf ”(即相同的地址)

您需要在消息前加上字元串“\x19Ethereum Signed Message:\n”和消息的長度

const prefix = new Buffer("\x19Ethereum Signed Message:\n");
const prefixedMsg = util.sha3(
Buffer.concat([prefix, new Buffer(String(msg.length)), msg])
);

然後在 ecrecover 中使用前綴字元串。

程式碼取自這裡的答案https://ethereum.stackexchange.com/a/12684/

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