I have signed a data string using the following code snippet in web3js
var data = "hello world";
web3.personal.sign(web3.fromUtf8(data), web3.eth.accounts[0], function(error, result) {
if (!error) {
console.log(data);
} else {
console.log(error);
}
});
Now I am trying to verify the address used to sign said string from web3j
public static boolean verifyAddressFromSignature(String address, String signature)
{
byte[] signatureBytes = Hash.sha3(signature).getBytes();
byte v = signatureBytes[64];
if(v < 27)
{
v += 27;
}
SignatureData sd = new SignatureData(v, (byte[]) Arrays.copyOfRange(signatureBytes, 0, 32), (byte[]) Arrays.copyOfRange(signatureBytes, 32, 64));
String addressRecovered = null;
boolean match = false;
// Iterate for each possible key to recover
for (int i = 0; i < 4; i++)
{
BigInteger publicKey = Sign.recoverFromSignature((byte) i, new ECDSASignature(new BigInteger(1, sd.getR()), new BigInteger(1, sd.getS())), signature.getBytes());
if (publicKey != null)
{
addressRecovered = "0x" + Keys.getAddress(publicKey);
System.out.println(addressRecovered);
if (addressRecovered.equals(address))
{
match = true;
break;
}
}
}
return match;
}
However, none of the generated addresses match the one used to create the signature.
Can anyone shed any light on what I am doing wrong?
Best Answer
https://github.com/web3j/web3j/blob/master/crypto/src/test/java/org/web3j/crypto/ECRecoverTest.java