Java报错HexUtil cannot be resolved

网上复制了一串代码,但是报错“HexUtil cannot be resolved”,怎么办

package ECDSA;
import javax.crypto.KeyAgreement;
import javax.xml.bind.DatatypeConverter;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
 
/**
 * ECCDSA加签验签工具类
 * @author Administrator
 *
 */
public class Ecdsa {
    
     private static final String SIGNALGORITHMS = "SHA256withECDSA";
     private static final String ALGORITHM = "EC";
     private static final String SECP256K1 = "secp256k1";
public static void main(String[] args) throws Exception {
 
//        生成公钥私钥
        KeyPair keyPair1 = getKeyPair();
        PublicKey publicKey1 = keyPair1.getPublic();
        PrivateKey privateKey1 = keyPair1.getPrivate();
        //密钥转16进制字符串
        String publicKey = HexUtil.encodeHexString(publicKey1.getEncoded());
        String privateKey = HexUtil.encodeHexString(privateKey1.getEncoded());
        System.out.println("生成公钥:"+publicKey);
        System.out.println("生成私钥:"+privateKey);
        //16进制字符串转密钥对象
        PrivateKey privateKey2 = getPrivateKey(privateKey);
        PublicKey publicKey2 = getPublicKey(publicKey);
        //加签验签
        String data="需要签名的数据";
        String signECDSA = signECDSA(privateKey2, data);
        boolean verifyECDSA = verifyECDSA(publicKey2, signECDSA, data);
        System.out.println("验签结果:"+verifyECDSA);
 
    }
 
    /**
     * 加签
     * @param privateKey 私钥
     * @param data 数据 
     * @return
     */
    public static String signECDSA(PrivateKey privateKey, String data) {
        String result = "";
        try {
            //执行签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            byte[] sign = signature.sign();
            return HexUtil.encodeHexString(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
 
    /**
     * 验签
     * @param publicKey 公钥
     * @param signed 签名
     * @param data 数据
     * @return
     */
    public static boolean verifyECDSA(PublicKey publicKey, String signed, String data) {
        try {
            //验证签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initVerify(publicKey);
            signature.update(data.getBytes());
            byte[] hex = HexUtil.decode(signed);
            boolean bool = signature.verify(hex);
           // System.out.println("验证:" + bool);
            return bool;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
 
   /**
    * 从string转private key
    * @param key 私钥的字符串
    * @return
    * @throws Exception
    */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        
        byte[] bytes = DatatypeConverter.parseHexBinary(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }
 
    /**
     * 从string转publicKey
     * @param key 公钥的字符串
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        
        byte[] bytes = DatatypeConverter.parseHexBinary(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }
 
 
    
 
    /**
     * 生成密钥对
     * @return
     * @throws Exception
     */
    public static KeyPair getKeyPair() throws Exception {
 
        ECGenParameterSpec ecSpec = new ECGenParameterSpec(SECP256K1);
        KeyPairGenerator kf = KeyPairGenerator.getInstance(ALGORITHM);
        kf.initialize(ecSpec, new SecureRandom());
        KeyPair keyPair = kf.generateKeyPair();
        return keyPair;
    }
}

HexUtil 这个类应该是他自己自定义的工具类,代码没有贴出来而已,可以找些替代的方法,我这里给换成apache-common包的hex,可以参考下


package ECDSA;

import org.apache.commons.codec.binary.Hex;
import javax.xml.bind.DatatypeConverter;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * ECCDSA加签验签工具类
 *
 * @author Administrator
 */
public class Ecdsa {

    private static final String SIGNALGORITHMS = "SHA256withECDSA";
    private static final String ALGORITHM = "EC";
    private static final String SECP256K1 = "secp256k1";

    public static void main(String[] args) throws Exception {

//        生成公钥私钥
        KeyPair keyPair1 = getKeyPair();
        PublicKey publicKey1 = keyPair1.getPublic();
        PrivateKey privateKey1 = keyPair1.getPrivate();
        //密钥转16进制字符串

        String publicKey = Hex.encodeHexString(publicKey1.getEncoded());
        String privateKey = Hex.encodeHexString(privateKey1.getEncoded());
        System.out.println("生成公钥:" + publicKey);
        System.out.println("生成私钥:" + privateKey);
        //16进制字符串转密钥对象
        PrivateKey privateKey2 = getPrivateKey(privateKey);
        PublicKey publicKey2 = getPublicKey(publicKey);
        //加签验签
        String data = "需要签名的数据";
        String signECDSA = signECDSA(privateKey2, data);
        boolean verifyECDSA = verifyECDSA(publicKey2, signECDSA, data);
        System.out.println("验签结果:" + verifyECDSA);

    }

    /**
     * 加签
     *
     * @param privateKey 私钥
     * @param data       数据
     * @return
     */
    public static String signECDSA(PrivateKey privateKey, String data) {
        String result = "";
        try {
            //执行签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            byte[] sign = signature.sign();
            return Hex.encodeHexString(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 验签
     *
     * @param publicKey 公钥
     * @param signed    签名
     * @param data      数据
     * @return
     */
    public static boolean verifyECDSA(PublicKey publicKey, String signed, String data) {
        try {
            //验证签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initVerify(publicKey);
            signature.update(data.getBytes());
            byte[] hex = Hex.decodeHex(signed);
            boolean bool = signature.verify(hex);
            // System.out.println("验证:" + bool);
            return bool;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 从string转private key
     *
     * @param key 私钥的字符串
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {

        byte[] bytes = DatatypeConverter.parseHexBinary(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 从string转publicKey
     *
     * @param key 公钥的字符串
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {

        byte[] bytes = DatatypeConverter.parseHexBinary(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }


    /**
     * 生成密钥对
     *
     * @return
     * @throws Exception
     */
    public static KeyPair getKeyPair() throws Exception {

        ECGenParameterSpec ecSpec = new ECGenParameterSpec(SECP256K1);
        KeyPairGenerator kf = KeyPairGenerator.getInstance(ALGORITHM);
        kf.initialize(ecSpec, new SecureRandom());
        KeyPair keyPair = kf.generateKeyPair();
        return keyPair;
    }
}


package ECDSA;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.xml.bind.DatatypeConverter;

/**
 * ECCDSA加签验签工具类
 * @author Administrator
 *
 */
public class Ecdsa {
     // 签名算法
     private static final String SIGNALGORITHMS = "SHA256withECDSA";
     // 密钥算法
     private static final String ALGORITHM = "EC";
     // 密钥类型
     private static final String SECP256K1 = "secp256k1";
     
     public static void main(String[] args) throws Exception {
        // 生成公钥私钥
        KeyPair keyPair1 = getKeyPair();
        PublicKey publicKey1 = keyPair1.getPublic();
        PrivateKey privateKey1 = keyPair1.getPrivate();
        // 将密钥转换为16进制字符串
        String publicKey = DatatypeConverter.printHexBinary(publicKey1.getEncoded());
        String privateKey = DatatypeConverter.printHexBinary(privateKey1.getEncoded());
        System.out.println("生成公钥:" + publicKey);
        System.out.println("生成私钥:" + privateKey);
        // 将16进制字符串转换为密钥对象
        PrivateKey privateKey2 = getPrivateKey(privateKey);
        PublicKey publicKey2 = getPublicKey(publicKey);
        // 加签验签
        String data = "需要签名的数据";
        String signECDSA = signECDSA(privateKey2, data);
        boolean verifyECDSA = verifyECDSA(publicKey2, signECDSA, data);
        System.out.println("验签结果:" + verifyECDSA);
    }
     
    /**
     * 加签
     * @param privateKey 私钥
     * @param data 数据 
     * @return 签名结果
     */
    public static String signECDSA(PrivateKey privateKey, String data) {
        String result = "";
        try {
            // 执行签名
            Signature signature = Signature.getInstance(SIGNALGORITHMS);
            signature.initSign(privateKey);
            signature.update(data.getBytes("UTF-8"));
byte[] sign = signature.sign();
// 将签名结果转换为16进制字符串
result = DatatypeConverter.printHexBinary(sign);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}/**
 * 验签
 * @param publicKey 公钥
 * @param signed 签名结果
 * @param data 数据
 * @return 验签结果
 */
public static boolean verifyECDSA(PublicKey publicKey, String signed, String data) {
    try {
        // 验证签名
        Signature signature = Signature.getInstance(SIGNALGORITHMS);
        signature.initVerify(publicKey);
        signature.update(data.getBytes("UTF-8"));
        // 将签名结果转换为字节数组
        byte[] hex = DatatypeConverter.parseHexBinary(signed);
        boolean bool = signature.verify(hex);
        return bool;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

/**
 * 获取密钥对
 * @return 密钥对
 */
public static KeyPair getKeyPair() {
    try {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec(SECP256K1);
        keyPairGenerator.initialize(ecGenParameterSpec);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        return keyPair;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * 获取私钥
 * @param privateKey 16进制字符串形式的私钥
 * @return 私钥对象
 */
public static PrivateKey getPrivateKey(String privateKey) {
    try {
        // 将16进制字符串转换为字节数组
        byte[] decode = DatatypeConverter.parseHexBinary(privateKey);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decode);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        return priKey;
    } catch (Exceptione) {
e.printStackTrace();
}
return null;
}/**
 * 获取公钥
 * @param publicKey 16进制字符串形式的公钥
 * @return 公钥对象
 */
public static PublicKey getPublicKey(String publicKey) {
    try {
        // 将16进制字符串转换为字节数组
        byte[] decode = DatatypeConverter.parseHexBinary(publicKey);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decode);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec);
        return pubKey;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

注释:

  • HexUtil 类中的 encodeHexStringdecode 方法替换为 java.xml.bind.DatatypeConverter 类中的 printHexBinaryparseHexBinary 方法。
  • 在加签和验签时,要使用相同的字符集编码数据。我在代码中使用了 UTF-8 编码。