Signing Data in Java and Web3j

This code example will demonstrate how to perform an ethereum personal sign operation in java using web3j. This will match signatures generated by the personal sign functions of web3js and geth.

byte[] messageToSign = "Testing Testing 123".getBytes();

//Create prefix
String prefix = "\u0019Ethereum Signed Message:\n" + messageToSign.length;

// Concat prefix and message
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );

try {
    outputStream.write(prefix.getBytes());
    outputStream.write(messageToSign);
} catch (IOException e) {
    throw new RuntimeException("Error when generating signature", e);
}

// Hash the prefixed message
byte[] hashedPrefixedMessage = Hash.sha3(outputStream.toByteArray());

// Create credentials (key pair) from mnemonic
Credentials credentials = WalletUtils.loadBip39Credentials("password", "mnemonic");

//Sign the hashed message with the credentials private key
Sign.SignatureData signedMessage = Sign.signMessage(
        hashedPrefixedMessage, credentials.getEcKeyPair(), false);

//Convert sig values from bytes[] to int / hex strings
int sigV = new BigInteger(signedMessage.getV()).intValue();
String hexSigR = Numeric.toHexString(signedMessage.getR());
String hexSigS = Numeric.toHexString(signedMessage.getS());

ecrecover can now be used to verify the message was in fact signed by the expected signee, either within a smart contract or off-chain. Awesome!