I am using web3j to verify message signatures but there are some false negative results.
For example this signature should be right, but it seems like the address could not be recovered:
final String address = "0x638aF69053892CDD7Ad295fC2482d1a11Fe5a9B7";
final String signature = "0x6c26935cc03e4e93c0bd1c3d068a54eb961bbc7db4ecf6c7b55b5b9bb073d32b61fcabeabd028322401ea62202726b520b84fd27aa7f8a8050dff728e064cebf1c";
final String message = "5893";
boolean isSignatureValid(final String address, final String signature, final String message) {
log.info("isSignatureValid invoked for Address {} with Signature {} and Message {} ", address, signature,
message);
final String personalMessagePrefix = "\u0019Ethereum Signed Message:\n";
boolean match = false;
final String prefix = personalMessagePrefix + message.length();
final byte[] msgHash = Hash.sha3((prefix + message).getBytes());
final byte[] signatureBytes = Numeric.hexStringToByteArray(signature);
byte v = signatureBytes[64];
if (v < 27) {
v += 27;
}
final SignatureData sd = new SignatureData(v,
Arrays.copyOfRange(signatureBytes, 0, 32),
Arrays.copyOfRange(signatureBytes, 32, 64));
String addressRecovered = null;
// Iterate for each possible key to recover
for (int i = 0; i < 4; i++) {
final BigInteger publicKey = Sign.recoverFromSignature((byte) i, new ECDSASignature(
new BigInteger(1, sd.getR()),
new BigInteger(1, sd.getS())), msgHash);
if (publicKey != null) {
addressRecovered = "0x" + Keys.getAddress(publicKey);
if (addressRecovered.equals(address)) {
match = true;
break;
}
}
}
return match;
}
}
I am still new in this area.