@Test public void signedMessageToKeyTest() throws SignatureException { ECKey key = new ECKey(); System.out.println(key.getPrivateKeyAsHex()); System.out.println(key.getPublicKeyAsHex()); String message = "Nuls Signed Message:\nHello,I'am test case！@##$%998877"; String signatureBase64 = key.signMessage(message,null); System.out.println(signatureBase64); System.out.println(Base64.decode(signatureBase64).length); ECKey recoveryECKey = ECKey.signedMessageToKey(message, signatureBase64); Assert.assertEquals(recoveryECKey.getPublicKeyAsHex(),key.getPublicKeyAsHex()); }
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 = formatMessageForSigning(message); Sha256Hash messageHash = Sha256Hash.twiceOf(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; }
ECKey { 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 = formatMessageForSigning(message); Sha256Hash messageHash = Sha256Hash.twiceOf(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; } }
ECKey { 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 = formatMessageForSigning(message); Sha256Hash messageHash = Sha256Hash.twiceOf(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; } ECKey();  ECKey(SecureRandom secureRandom); private  ECKey(BigInteger priv, ECPoint pub); }
ECKey { 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 = formatMessageForSigning(message); Sha256Hash messageHash = Sha256Hash.twiceOf(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; } ECKey();  ECKey(SecureRandom secureRandom); private  ECKey(BigInteger priv, ECPoint pub); static ECKey fromPrivate(BigInteger privKey); static ECKey fromPrivate(BigInteger privKey, boolean compressed); static ECKey fromPublicOnly(byte[] pubKey); static ECKey fromPublicOnly(ECPoint pub); static ECPoint publicPointFromPrivate(BigInteger privKey); static ECKey fromEncrypted(EncryptedData encryptedPrivateKey, byte[] pubKey); byte[] getPubKey(); @JsonIgnore BigInteger getPrivKey(); @JsonIgnore byte[] getPrivKeyBytes(); @JsonIgnore String getPrivateKeyAsHex(); String getPublicKeyAsHex(); String getPublicKeyAsHex(boolean compressed); static boolean verify(byte[] data, ECDSASignature signature, byte[] pub); static boolean verify(byte[] data, byte[] signature, byte[] pub); boolean verify(byte[] hash, byte[] signature); byte[] sign(byte[] hash); byte[] sign(Sha256Hash hash, BigInteger aesKey); byte[] sign(byte[] hash, BigInteger aesKey); boolean hasPrivKey(); boolean isCompressed(); void setCreationTimeSeconds(long creationTimeSeconds); long getCreationTimeSeconds(); EncryptedData getEncryptedPrivateKey(); void setEncryptedPrivateKey(EncryptedData encryptedPrivateKey); static boolean isValidPrivteHex(String privateHex); static ECKey signedMessageToKey(String message, String signatureBase64); @Nullable static ECKey recoverFromSignature(int recId, ECDSASignature sig, Sha256Hash message, boolean compressed); String signMessage(String message, @Nullable KeyParameter aesKey); byte findRecoveryId(Sha256Hash hash, ECDSASignature sig); }
ECKey { 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 = formatMessageForSigning(message); Sha256Hash messageHash = Sha256Hash.twiceOf(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; } ECKey();  ECKey(SecureRandom secureRandom); private  ECKey(BigInteger priv, ECPoint pub); static ECKey fromPrivate(BigInteger privKey); static ECKey fromPrivate(BigInteger privKey, boolean compressed); static ECKey fromPublicOnly(byte[] pubKey); static ECKey fromPublicOnly(ECPoint pub); static ECPoint publicPointFromPrivate(BigInteger privKey); static ECKey fromEncrypted(EncryptedData encryptedPrivateKey, byte[] pubKey); byte[] getPubKey(); @JsonIgnore BigInteger getPrivKey(); @JsonIgnore byte[] getPrivKeyBytes(); @JsonIgnore String getPrivateKeyAsHex(); String getPublicKeyAsHex(); String getPublicKeyAsHex(boolean compressed); static boolean verify(byte[] data, ECDSASignature signature, byte[] pub); static boolean verify(byte[] data, byte[] signature, byte[] pub); boolean verify(byte[] hash, byte[] signature); byte[] sign(byte[] hash); byte[] sign(Sha256Hash hash, BigInteger aesKey); byte[] sign(byte[] hash, BigInteger aesKey); boolean hasPrivKey(); boolean isCompressed(); void setCreationTimeSeconds(long creationTimeSeconds); long getCreationTimeSeconds(); EncryptedData getEncryptedPrivateKey(); void setEncryptedPrivateKey(EncryptedData encryptedPrivateKey); static boolean isValidPrivteHex(String privateHex); static ECKey signedMessageToKey(String message, String signatureBase64); @Nullable static ECKey recoverFromSignature(int recId, ECDSASignature sig, Sha256Hash message, boolean compressed); String signMessage(String message, @Nullable KeyParameter aesKey); byte findRecoveryId(Sha256Hash hash, ECDSASignature sig); static final ECDomainParameters CURVE; static final BigInteger HALF_CURVE_ORDER; static final Comparator<ECKey> PUBKEY_COMPARATOR; }