I'm new in web3 and I'm trying to develop a way to authenticate users in my dapp. I'm used to using the old and safe method with email + password to do that, but recently I realised that I could use signatures instead of my old method.
The idea is simple:
- user signs a message and sends it to the backend for verification and authentication
- backend decodes it and compares the caller's address with signer's address
- backend marks this signature on his side as used and generates auth token to caller
- user receives an auth token and has the same access as he could have with the default method e.g. jwt
So, now my frontend uses any web3 wallet and tries to do something like this:
const mess = 'some message user signs'
const signature = await web3.eth.personal.sign(mess, address)
await axios.post(backendUrlAuth, {address: address, signature: signature, signedMessage: mess}, cfg)
Then backend verifies it this way:
public boolean verify(String address, String signature, String signedMessage) throws SignatureException {
if (address.startsWith("0x")) {
address = address.substring(2);
}
if (signature.startsWith("0x")) {
signature = signature.substring(2);
}
var r = signature.substring(0, 64);
var s = signature.substring(64, 128);
var v = signature.substring(128, 130);
var publicKey = Sign.signedPrefixedMessageToKey(signedMessage.getBytes(),
new Sign.SignatureData(
Numeric.hexStringToByteArray(v)[0],
Numeric.hexStringToByteArray(r),
Numeric.hexStringToByteArray(s)))
.toString(16);
return Keys.getAddress(publicKey).equals(address);
}
So, I'm here to ask is this way safe or not ?