1

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.

0

This should help you:

public static String getAddressUsedToSignHashedMessage(String signedHash, String originalMessageHashInHex) throws SignatureException {
        byte[] messageHashBytes = Numeric.hexStringToByteArray(originalMessageHashInHex);
        String r = signedHash.substring(0, 66);
        String s = "0x"+signedHash.substring(66, 130);
        String v = "0x"+signedHash.substring(130, 132);
        System.out.println();
        byte[] msgBytes = new byte[GETH_SIGN_PREFIX.getBytes().length + messageHashBytes.length];
        byte[] prefixBytes = GETH_SIGN_PREFIX.getBytes();
        System.arraycopy(prefixBytes, 0, msgBytes, 0, prefixBytes.length);
        System.arraycopy(messageHashBytes, 0, msgBytes, prefixBytes.length, messageHashBytes.length);
        String pubkey = Sign.signedMessageToKey(msgBytes,
                new Sign.SignatureData(Numeric.hexStringToByteArray(v)[0],
                        Numeric.hexStringToByteArray(r),
                        Numeric.hexStringToByteArray(s)))
                .toString(16);
        System.out.println("");
        System.out.println("Pubkey: " + pubkey);
        String address = Keys.getAddress(pubkey);
        return address;
    }

Reference: https://gist.github.com/megamattron/94c05789e5ff410296e74dad3b528613

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.