java用ED25519算法实现签名验签

首先要引入下面的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;
    }
posted @ 2021-03-12 15:58  Conwie  阅读(2000)  评论(0编辑  收藏  举报