Skip to content

Instantly share code, notes, and snippets.

@megamattron
Created November 21, 2017 14:31
Show Gist options
  • Save megamattron/94c05789e5ff410296e74dad3b528613 to your computer and use it in GitHub Desktop.
Save megamattron/94c05789e5ff410296e74dad3b528613 to your computer and use it in GitHub Desktop.
import org.web3j.crypto.Keys;
import org.web3j.crypto.Sign;
import org.web3j.utils.Numeric;
import java.security.SignatureException;
public class SignUtil {
private static final String GETH_SIGN_PREFIX = "\u0019Ethereum Signed Message:\n32";
/**
* This method is expecting the signed message to be a hash of the original message. The length of the message is
* then hardcoded to 32. Also, this might only work for messages signed by geth, not sure if other clients
* add the prefix to the signed message.
* @param signedHash
* @param originalMessageHashInHex
* @return
* @throws SignatureException
*/
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;
}
}
@kuncle
Copy link

kuncle commented Mar 28, 2023

 public static String ecRecover(String msg, String sig) {
    byte[] signatureBytes = Numeric.hexStringToByteArray(sig);
    Sign.SignatureData signatureData = sigFromByteArray(signatureBytes);

    try {
        BigInteger recoveredKey = Sign.signedPrefixedMessageToKey(msg.getBytes(), signatureData);
        String address = "0x" + Keys.getAddress(recoveredKey);
        return address.toLowerCase();
    } catch (Exception e) {
        log.error("SignatureException, msg:{}, sig:{}, nonce:{}: ", msg, sig, nonce, e.getMessage());
    }
}

public static Sign.SignatureData sigFromByteArray(byte[] sig) {
    if (sig.length < 64 || sig.length > 65) return null;
    byte  v = sig[64];
    if (v < 27) v += 27;

    byte[] r = Arrays.copyOfRange(sig, 0, 32);
    byte[] s = Arrays.copyOfRange(sig, 32, 64);

    return new Sign.SignatureData(v, r, v);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment