首先要引入下面的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;
}