首先要引入下面的jar包:
<dependency>
<groupId>net.i2p.crypto</groupId>
<artifactId>eddsa</artifactId>
<version>0.3.0</version>
</dependency>
下面是ED25519算法实现签名验签的一个demo:
@Slf4j
public class EDTest {
// 公私钥是由64个字节(128位16进制)构成的,前32个字节是私钥,后32个字节是公钥
public static String key = "89680894b7ce1c5c91eba3468589787ffe340f357759bbf5bbfacb685ffc1bb914e0ea07e8766d71a15f7712fd1e2bebe8ad8080bf1ca2e6753caf64b61e80b3";
public static void main(String[] args) throws Exception {
// data数据(JSON)
String data = "123456";
// 公私钥转为byte[]
byte[] seed = Utils.hexToBytes(key);
// 取前32位字节私钥
byte[] privSeed = Arrays.copyOfRange(seed, 0, 32);
// ed25519 签名
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
Signature signature = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(privSeed, spec);
PrivateKey sKey = new EdDSAPrivateKey(privKey);
// 私钥 签名
signature.initSign(sKey);
// 把你的data用SHA256加密
signature.update(NodeUtils.getSHA256(data));
// 签名转换为hex
String sign = Utils.bytesToHex(signature.sign());
// 取后32位字节公钥
byte[] pubSeed = Arrays.copyOfRange(seed, 32, seed.length);
// 用公钥验证签名
EdDSAParameterSpec spec2 = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
Signature signature2 = new EdDSAEngine(MessageDigest.getInstance(spec2.getHashAlgorithm()));
EdDSAPublicKeySpec pubKeySpec = new EdDSAPublicKeySpec(pubSeed, spec2);
PublicKey pKey = new EdDSAPublicKey(pubKeySpec);
// 公钥 验证返回的sign
signature2.initVerify(pKey);
// 对返回的data加密SHA256 验证
signature2.update(NodeUtils.getSHA256(data));
boolean verify = signature2.verify(Utils.hexToBytes(sign));
log.info("签名验证结果为:{}", verify);
}
}
实现SHA256加密的方法:
/**
* 用java原生的摘要实现SHA256加密
*
* @param str 加密前的报文
* @return
*/
public static byte[] getSHA256(String str) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes("UTF-8"));
return messageDigest.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}