BitcoinJ and message verifying

1.1k Views Asked by At

Given three pieces of information: message (string), signature (string), and public address (string), I want to verify the signature. In libraries for Javascript, Python and PHP this is a simple method call. However in BitcoinJ (Java), I cannot come up with a simple solution or example.

First, I only want to verify a signature. BitcoinJ is overkill, but it's the only Java library I've been able to find. It also doesn't seem to have a direct method call for what I need. There is a method call that requires the public key, but I have the public address. Discussions around the web indicate that the public key can be sourced from the signature. However it appears this isn't as straight forward as it sounds. Java also wants bytes instead of strings. Sounds easy enough, but efforts are not working. There are no examples I can find.

So can someone provide me an example of a simple message verification in Java (BitcoinJ or otherwise) with the above three pieces of information? TIA!

2

There are 2 best solutions below

1
On

Posting my own answer:

String loginSig = ""; // base64 encoded signature
String pubAddress = ""; // bitcoin public address
String message = "Hello World";

ECKey result = new ECKey().signedMessageToKey(message, loginSig);

if (pubAddress.equals(result.toAddress(NetworkParameters.prodNet()).toString())) {
    // success!
}
0
On

Here is a correction of mohrt answer without the deprecated call, and guessing the network from the provided address.

/**
 * Validate a signature.
 *
 * @param address   Bitcoin address
 * @param signature Signature content
 * @param message   Signed message
 * @return true if the signature of a given message by the given address is correct.
 */
public boolean isValidSignature(String address, String signature, String message) {
    try {
        return ECKey.signedMessageToKey(message, signature).toAddress(Address.fromBase58(null, address).getParameters()).toString().equals(address);
    } catch (Exception e) {
        return false;
    }
}