I have seen this question and others but none answers my qustion.
How can I sign a message and make sure that the public key I recover is actually belongs to the private key that signed the message?
The code below has been inspired by this github thread.
// function in the front-end.
async signMessage(){
const message = `Hello World`;
const messageHash = await ethers.utils.hashMessage(message)
const signedMessage = await this.signer.signMessage(ethers.utils.arrayify(messageHash));
//...........
//Send messageHash and signedMessage to the server backend
}
Backend code:
// function in the back-end.
async verifyMessage(messageHash, signedMessage){
const pubkey = ethers.utils.recoverPublicKey(
ethers.utils.arrayify(
ethers.utils.hashMessage(ethers.utils.arrayify(messageHash))
),
signedMessage
)
const address = ethers.utils.computeAddress(pubkey)
}
1st problem with the code above is that someone(e.g a malicious party) can use the signature again and again(without resigning it) and the backend would not be able to know so.
2nd problem you can submit a message that is different to the one that is signed and the back-end would not be able to know. In fact a valid ethereum address would still be recovered.
How can this be solved?