Signature

EcRecover 簽名消息與 PublicAddress 不匹配

  • August 5, 2021

我正在嘗試創建一個 C# webservice 後端 API 來處理步驟 #5 中的程式碼邏輯: https ://www.toptal.com/ethereum/one-click-login-flows-a-metamask-tutorial

他們的程式碼如下所示:

User.findOne({ where: { publicAddress } })
 // --snip--
 .then(user => {
   const msg = `I am signing my one-time nonce: ${user.nonce}`;

   // We now are in possession of msg, publicAddress and signature. We
   // can perform an elliptic curve signature verification with ecrecover
   const msgBuffer = ethUtil.toBuffer(msg);
   const msgHash = ethUtil.hashPersonalMessage(msgBuffer);
   const signatureBuffer = ethUtil.toBuffer(signature);
   const signatureParams = ethUtil.fromRpcSig(signatureBuffer);
   const publicKey = ethUtil.ecrecover(
     msgHash,
     signatureParams.v,
     signatureParams.r,
     signatureParams.s
   );
   const addressBuffer = ethUtil.publicToAddress(publicKey);
   const address = ethUtil.bufferToHex(addressBuffer);

   // The signature verification is successful if the address found with
   // ecrecover matches the initial publicAddress
   if (address.toLowerCase() === publicAddress.toLowerCase()) {
     return user;
   } else {
     return res
       .status(401)
       .send({ error: 'Signature verification failed' });
   }
 })

我的程式碼如下所示。但它總是返回 false。我的第一個猜測是“消息”格式不正確。我見過其他範例不包括“\x19”部分,但刪除它並包含它都返回 false。

public static bool AccountSignerIsValid(string signature, string publicAddress)
{
   var nonce = "12345678";
   var terms = "Please sign to log in: " + nonce;
   var message = Encoding.UTF8.GetBytes("\x19Ethereum Signed Message:\n" + terms.Length + terms);
   var hash = (new Sha3Keccack()).CalculateHash(message.ToArray());

   var signer = new Nethereum.Signer.MessageSigner();
   var account = signer.EcRecover(hash, signature);

   return (account.ToLower().Equals(publicAddress.ToLower()));
}

我需要做什麼來更改 C# 程式碼以使其返回 true?

//  ("\x19Ethereum")  !=  ("\x19" + "Ethereum")
var message = Encoding.UTF8.GetBytes("\x19" + "Ethereum Signed Message:\n" + terms.Length + terms);

對於其他到達這裡的人,有一個內置函式負責編碼、散列、驗證和建構字元串:

var recoveredAddress = signer.EncodeUTF8AndEcRecover(message, signature);

請注意,恢復的地址以混合大小寫形式出現(內置校驗和),因此請進行 IgnoreCase 比較或將它們都小寫。

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