I am trying to create a C# webservice back end API that handles the code logic found in Step #5 here: https://www.toptal.com/ethereum/one-click-login-flows-a-metamask-tutorial
Their code looks like this:
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' });
}
})
My code looks like this, below. But it always returns false. My first guess is that the "message" format is incorrect somehow. I've seen other examples not include the "\x19" portion, but removing it and including it both returns 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()));
}
What would I need to do to change the C# code to make it return true?