Web3j: Web3J Sign VS Web3JS - different results

Created on 11 Jan 2018  路  4Comments  路  Source: web3j/web3j

Hello,
I'm trying to reproduce using java this nodejs script using web3js to sign a message:

var Accounts = require('web3-eth-accounts');
var Web3 = require('web3')
var web3 = new Web3();
var accounts = new Accounts();
var privateKey1 = "7196933fe363871920c59be78aa5c478bf6e6271532db5d0ce3b090518f91f03"
var acc = accounts.privateKeyToAccount(privateKey1);
var sig = acc.sign('TEST');
console.log(sig.r);
console.log(sig.s);
console.log(sig.v);

The java code is:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.Sign;
import org.web3j.utils.Numeric;

public class Test {
 public static void main(String[] args) throws NoSuchAlgorithmException
 {
     String privateKey1 = "7196933fe363871920c59be78aa5c478bf6e6271532db5d0ce3b090518f91f03";
     Credentials credentials = Credentials.create(privateKey1);
     String testString = "TEST";//"\u0019Ethereum Signed Message:\n" + "TEST".length() + "TEST";

     MessageDigest digest = MessageDigest.getInstance("SHA-256");
     byte[] hash = digest.digest(MyTypeEncoder.hexStringToByteArray("\u0019Ethereum Signed Message:\n32"+"TEST"));

     //MySign.SignatureData signatureData = MySign.signMessage(testString.getBytes(), credentials.getEcKeyPair());
     MySign.SignatureData signatureData = MySign.signHash(hash, credentials.getEcKeyPair());

     //Sign.SignatureData signatureData = Sign.signMessage(testString.getBytes(), credentials.getEcKeyPair());
     System.out.println("R: " + Numeric.toHexString(signatureData.getR()));
     System.out.println("S: " + Numeric.toHexString(signatureData.getS()));
     System.out.println("V: " + signatureData.getV());
 }
}

I tried with "TEST", "TEST" with the prefix, using the original Sign class... all with no success. I then wrote a MySign class that has two different methods: signHash and signMessage (so that you can decide to create the hash yourself and sign it).
Tried to sign the message directly, or to generate an hash and then sign it, with no success.

Most helpful comment

im having the same problem, can we get some help? the signature web3j gives is not the same as the one produced by web3js

All 4 comments

SHA-256 is not the same as Keccak 256 used in Ethereum.

See Hash and the following issues, https://github.com/web3j/web3j/issues/194 and https://github.com/web3j/web3j/issues/208.

Thanks, will try with the tips you gave me.

is this closed? but i did it the same way, but it didn't work! can you help me?
This is my verify code:

 function validate(uint8 v,bytes32 r,bytes32 s,uint number)  view returns (bool){

        bytes memory prefix = "\x19Ethereum Signed Message:\n32";

         bytes32 prefixedHash = sha3(prefix,sha3(uint2str(number)));

        address endecodedAddress = ecrecover(prefixedHash, v, r, s);

        return msg.sender == endecodedAddress;

  }

i use web3j in my java code:

Credentials credentials = WalletUtils.loadCredentials("121212",
                "/home/linfang/workspace/go/src/go-ethereum/data1/keystore/UTC--2018-04-04T01-47-13.603875992Z--5263718fe22d48cb854ad3e22c552b7c85de111f");
        String hash = Hash.sha3(Numeric.toHexStringNoPrefix("2000".getBytes()));
        System.out.println("Hash: " + hash);

        String message = "\\x19Ethereum Signed Message:\n" + hash.length() + hash;
        byte[] data = message.getBytes();

        Sign.SignatureData signature = Sign.signMessage(data, credentials.getEcKeyPair());
        System.out.println("R: " + Numeric.toHexString(signature.getR()));
        System.out.println("S: " + Numeric.toHexString(signature.getS()));
        System.out.println("V: " + Integer.toString(signature.getV()));

the result of java is:

R: 0x6fc2de95a1b1a64d97891c1c60a00a0f91c3fa5f7c9e3b73d6dc1f2518c5e3c4
S: 0x4b1a22d9cf41b33ba9c4c82b33dc127e80123d9fecc3187c2a7f3ef44c8d994c
V: 28

i use web3 in geth:

msg = web3.sha3('2000')
signature = web3.eth.sign(acc3, msg)
r = signature.slice(0, 66)
s = '0x' + signature.slice(66, 130)
v = '0x' + signature.slice(130, 132)
v = web3.toDecimal(v)

the result in web3 is:

R:0xc4a5f7b46af70e764f947bb383574f40156234f5bb9e339d2ef71dd1f53a92bf
S:0x0a882ea5de8171683ab89e4875a53f6ae6a526d5195ae111180dc9569c9b4edf
v:28

I am sure the credentials is the same銆倃hy i still can't pass!

im having the same problem, can we get some help? the signature web3j gives is not the same as the one produced by web3js

Was this page helpful?
0 / 5 - 0 ratings