public static ECKey signedMessageToKey(String message,String signatureBase64) throws SignatureException {
  byte[] signatureEncoded;
  try {
    signatureEncoded=Base64.decode(signatureBase64);
  }
 catch (  RuntimeException e) {
    throw new SignatureException("Could not decode base64",e);
  }
  if (signatureEncoded.length < 65)   throw new SignatureException("Signature truncated, expected 65 bytes and got " + signatureEncoded.length);
  int header=signatureEncoded[0] & 0xFF;
  if (header < 27 || header > 34)   throw new SignatureException("Header byte out of range: " + header);
  BigInteger r=new BigInteger(1,Arrays.copyOfRange(signatureEncoded,1,33));
  BigInteger s=new BigInteger(1,Arrays.copyOfRange(signatureEncoded,33,65));
  ECDSASignature sig=new ECDSASignature(r,s);
  byte[] messageBytes=Utils.formatMessageForSigning(message);
  Sha256Hash messageHash=Sha256Hash.createDouble(messageBytes);
  boolean compressed=false;
  if (header >= 31) {
    compressed=true;
    header-=4;
  }
  int recId=header - 27;
  ECKey key=ECKey.recoverFromSignature(recId,sig,messageHash,compressed);
  if (key == null)   throw new SignatureException("Could not recover public key from signature");
  return key;
}

public static ECKey signedMessageToKey ( String message , String signatureBase64 ) throws SignatureException { byte [ ] signatureEncoded ; try { signatureEncoded = Base64 . decode ( signatureBase64 ) ; } catch ( RuntimeException e ) { throw new SignatureException ( "Could not decode base64" , e ) ; } if ( signatureEncoded . length < 65 ) throw new SignatureException ( "Signature truncated, expected 65 bytes and got " + signatureEncoded . length ) ; int header = signatureEncoded [ 0 ] & 0xFF ; if ( header < 27 || header > 34 ) throw new SignatureException ( "Header byte out of range: " + header ) ; BigInteger r = new BigInteger ( 1 , Arrays . copyOfRange ( signatureEncoded , 1 , 33 ) ) ; BigInteger s = new BigInteger ( 1 , Arrays . copyOfRange ( signatureEncoded , 33 , 65 ) ) ; ECDSASignature sig = new ECDSASignature ( r , s ) ; byte [ ] messageBytes = Utils . formatMessageForSigning ( message ) ; Sha256Hash messageHash = Sha256Hash . createDouble ( messageBytes ) ; boolean compressed = false ; if ( header >= 31 ) { compressed = true ; header -= 4 ; } int recId = header - 27 ; ECKey key = ECKey . recoverFromSignature ( recId , sig , messageHash , compressed ) ; if ( key == null ) throw new SignatureException ( "Could not recover public key from signature" ) ; return key ; }
given an arbitrary piece of text and a bitcoin - format message signature encoded in base64 , returns an eckey containing the public key that was used to sign it . this can then be compared to the expected public key to determine if the signature was correct . these sorts of signatures are compatible with the bitcoin - qt / bitcoind format generated by signmessage / verifymessage rpcs and gui menu options . they are intended for humans to verify their communications with each other , hence the base64 format and the fact that the input is text .
