Ed25519加密解密

pom.xml

        <!-- 加密算法 -->
        <dependency>
            <groupId>net.i2p.crypto</groupId>
            <artifactId>eddsa</artifactId>
            <version>0.3.0</version>
        </dependency>

 

LicenseEdDSA.java
import net.i2p.crypto.eddsa.EdDSAEngine;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.Utils;
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;

import java.security.*;
import java.util.HashMap;
import java.util.Map;


public class LicenseEdDSA {

    private final static String PRIVATE_KEY = "privateKey";
    private final static String PUBLIC_KEY = "publicKey";

    public static void main(String[] args) {
        // 公私钥是由64个字节(128位16进制)构成的,前32个字节是私钥,后32个字节是公钥
        // 1,获取公私钥
        Map<String, String> keyMap = keyPairGenerator();
        String privateKey = keyMap.get(PRIVATE_KEY);
        String publicKey = keyMap.get(PUBLIC_KEY);
        // data数据(JSON)
        String data = "123456";

        // 2,数据私钥加密
        String sign = signData(data, privateKey);

        // 3,数据公钥验证
        boolean verify = verify(data, sign, publicKey);
        System.out.println("verify = " + verify);
    }


    public static String signData(String data, String privateKey) {

        try {
            // 私钥转为byte[]
            byte[] privSeed = Utils.hexToBytes(privateKey);
            // 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(getSHA256(data));
            // 签名转换为hex
            String sign = Utils.bytesToHex(signature.sign());
            return sign;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public static boolean verify(String data, String sign, String publicKey) {
        try {
            // 公钥转为byte[]
            byte[] pubSeed = Utils.hexToBytes(publicKey);
            // 用公钥验证签名
            EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
            Signature signature = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
            EdDSAPublicKeySpec pubKeySpec = new EdDSAPublicKeySpec(pubSeed, spec);
            PublicKey pKey = new EdDSAPublicKey(pubKeySpec);
            // 公钥 验证返回的sign
            signature.initVerify(pKey);
            // 对返回的data加密SHA256 验证
            signature.update(getSHA256(data));
            boolean verify = signature.verify(Utils.hexToBytes(sign));
            return verify;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

    }

    /**
     * 用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 (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Map<String, String> keyPairGenerator() {
        EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
        SecureRandom random = new SecureRandom();

        // 生成私钥(32字节)
        byte[] privateKey = new byte[32];
        random.nextBytes(privateKey);

        // 计算公钥(通过私钥推导)
        EdDSAPrivateKeySpec privateKeySpec = new EdDSAPrivateKeySpec(privateKey, spec);
        EdDSAPublicKeySpec publicKeySpec = new EdDSAPublicKeySpec(privateKeySpec.getA().toByteArray(), spec);

        // 二进制转十六进制
        String privateKeyHex = Utils.bytesToHex(privateKey);
        String publicKeyHex = Utils.bytesToHex(publicKeySpec.getA().toByteArray());

        Map<String, String> keyMap = new HashMap<>(2);
        keyMap.put(PRIVATE_KEY, privateKeyHex);
        keyMap.put(PUBLIC_KEY, publicKeyHex);
        return keyMap;
    }

}

 

posted @ 2025-05-21 11:17  真某人  阅读(100)  评论(0)    收藏  举报