Java常见加密解密算法整合工具Util

废话不多说,直接上代码

1.源码

package com.visy.utils;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Objects;
import java.util.function.Function;

/**
 * 加密工具
 * @author visy.wang
 * @date 2024/9/5 10:29
 */
public class CryptoUtil {
    private static final Logger logger = LoggerFactory.getLogger(CryptoUtil.class);

    /**
     * BASE64
     * 网络上最常见的用于传输8Bit字节码的编码方式之一,就是一种基于64个可打印字符来表示二进制数据的方法
     * 包括小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"一共64个字符的字符集
     * 任何符号都可以转换成这个字符集中的字符,这个转换过程就叫做base64编码
     *
     */
    public static class BASE64 {
        public static Base64.Encoder encoder = Base64.getEncoder();
        public static Base64.Decoder decoder = Base64.getDecoder();
        //对URL的编码方式,替换“+” “/” 为“-” “_”
        public static Base64.Encoder urlEncoder = Base64.getUrlEncoder();
        public static Base64.Decoder urlDecoder = Base64.getUrlDecoder();

        public static byte[] encode(byte[] data) {
            return encoder.encode(data);
        }
        public static String encodeToStr(byte[] data) {
            return bytesToStr(encode(data));
        }
        public static String encode(String data) {
            return encodeToStr(strToBytes(data));
        }
        public static byte[] encodeToBytes(String data) {
            return encode(strToBytes(data));
        }
        public static byte[] urlEncode(byte[] data) {
            return urlEncoder.encode(data);
        }
        public static String urlEncodeToStr(byte[] data) {
            return bytesToStr(urlEncode(data));
        }
        public static String urlEncode(String data) {
            return urlEncodeToStr(strToBytes(data));
        }
        public static byte[] urlEncodeToBytes(String data) {
            return urlEncode(strToBytes(data));
        }
        public static byte[] decode(byte[] data) {
            return decoder.decode(data);
        }
        public static String decodeToStr(byte[] data) {
            return bytesToStr(decode(data));
        }
        public static String decode(String data) {
            return decodeToStr(strToBytes(data));
        }
        public static byte[] decodeToBytes(String data) {
            return decode(strToBytes(data));
        }
        public static byte[] urlDecode(byte[] data) {
            return urlDecoder.decode(data);
        }
        public static String urlDecodeToStr(byte[] data) {
            return bytesToStr(urlDecode(data));
        }
        public static String urlDecode(String data) {
            return urlDecodeToStr(strToBytes(data));
        }
        public static byte[] urlDecodeToBytes(String data) {
            return urlDecode(strToBytes(data));
        }
        private static byte[] strToBytes(String str){
            return str.getBytes(StandardCharsets.UTF_8);
        }
        private static String bytesToStr(byte[] bytes){
            return new String(bytes, StandardCharsets.UTF_8);
        }
    }

    /**
     * 对称加密
     */
    private static class SymCrypto {
        /**
         * 初始化向量的长度
         */
        private static final int IV_LENGTH = 16;
        /**
         * 生成密匙
         * @param cryptoType 加密类型
         * @return 密匙
         */
        public static String generateKey(CryptoType cryptoType) {
            return generateKey(cryptoType, null);
        }
        /**
         * 生成密匙
         * @param cryptoType 加密类型
         * @param size 密匙长度
         * @return 密匙
         */
        public static String generateKey(CryptoType cryptoType, Integer size) {
            String algorithm = cryptoType.getAlgorithm();
            try {
                KeyGenerator generator = KeyGenerator.getInstance(algorithm);
                if(Objects.isNull(size)){
                    generator.init(new SecureRandom());
                }else{
                    generator.init(size, new SecureRandom());
                }
                byte[] key = generator.generateKey().getEncoded();
                return BASE64.encodeToStr(key);
            } catch (NoSuchAlgorithmException e) {
                throw CryptoException.of(algorithm+"生成密匙异常", e);
            }
        }
        /**
         * 加密
         * @param data 明文
         * @param key 密匙
         * @param cryptoType 加密类型
         * @return 密文
         */
        public static String encrypt(String data, String key, CryptoType cryptoType) {
            String algorithm = cryptoType.getAlgorithm();
            try {
                SecureRandom sr = new SecureRandom();
                String cipherName = cryptoType.getCipher();
                Cipher cipher = Cipher.getInstance(cipherName);
                byte[] plaintext = BASE64.strToBytes(data);
                SecretKey secretKey = cryptoType.getSecretKey(BASE64.decodeToBytes(key));
                if(cipherName.contains("/CBC/")){
                    //CBC模式,需要生成一个16位的初始化向量,同一明文每次生成的密文不一样(类似于加盐)
                    byte[] iv = sr.generateSeed(IV_LENGTH);
                    cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
                    byte[] ciphertext = cipher.doFinal(plaintext);
                    //拼接iv和加密结果
                    byte[] result = new byte[iv.length + ciphertext.length];
                    System.arraycopy(iv, 0, result, 0, iv.length);
                    System.arraycopy(ciphertext, 0, result, iv.length, ciphertext.length);
                    return BASE64.encodeToStr(result);
                }else{
                    //ECB模式,不需要初始化向量,同一明文每次生成的密文一样
                    cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
                    byte[] ciphertext = cipher.doFinal(plaintext);
                    return BASE64.encodeToStr(ciphertext);
                }
            } catch (Exception e) {
                throw CryptoException.of(algorithm+"加密异常", e);
            }
        }
        /**
         * 解密
         * @param data 密文
         * @param key 密匙
         * @param cryptoType 加密类型
         * @return 明文
         */
        public static String decrypt(String data, String key, CryptoType cryptoType) {
            String algorithm = cryptoType.getAlgorithm();
            try {
                byte[] ciphertext;
                String cipherName = cryptoType.getCipher();
                byte[] dataBytes = BASE64.decodeToBytes(data);
                Cipher cipher = Cipher.getInstance(cipherName);
                SecretKey secretKey = cryptoType.getSecretKey(BASE64.decodeToBytes(key));
                if(cipherName.contains("/CBC/")){
                    //CBC模式
                    //把data分割成IV和密文
                    byte[] iv = new byte[IV_LENGTH];
                    ciphertext = new byte[dataBytes.length-IV_LENGTH];
                    System.arraycopy(dataBytes, 0, iv, 0, IV_LENGTH);//复制IV
                    System.arraycopy(dataBytes, IV_LENGTH, ciphertext, 0, ciphertext.length);//复制密文
                    cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
                }else{
                    //ECB模式
                    ciphertext = dataBytes;
                    cipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());
                }
                byte[] plaintext = cipher.doFinal(ciphertext);
                return BASE64.bytesToStr(plaintext);
            } catch (Exception e) {
                throw CryptoException.of(algorithm+"解密异常", e);
            }
        }
    }

    /**
     * 非对称加密
     */
    private static class AsymCrypto {
        /**
         * 生成密匙对
         * @param cryptoType 加密类型
         * @param size 密匙长度
         * @return 密匙对
         */
        public static StrKeyPair generateKeyPair(CryptoType cryptoType, Integer size){
            String algorithm = cryptoType.getAlgorithm();
            try {
                KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm);
                generator.initialize(size, new SecureRandom());
                KeyPair keyPair = generator.generateKeyPair();
                return StrKeyPair.of(keyPair);
            }catch (NoSuchAlgorithmException e) {
                throw CryptoException.of(algorithm+"生成密匙对异常", e);
            }
        }
        /**
         * 加密
         * @param data 明文
         * @param pubKey 公钥
         * @param cryptoType 加密类型
         * @return 密文
         */
        public static String encrypt(String data, String pubKey, CryptoType cryptoType) {
            String algorithm = cryptoType.getAlgorithm();
            try {
                byte[] plaintext = BASE64.strToBytes(data);
                KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
                KeySpec keySpec = new X509EncodedKeySpec(BASE64.decodeToBytes(pubKey));
                PublicKey publicKey = keyFactory.generatePublic(keySpec);
                Cipher cipher = Cipher.getInstance(cryptoType.getCipher());
                cipher.init(Cipher.ENCRYPT_MODE, publicKey, new SecureRandom());
                byte[] ciphertext = cipher.doFinal(plaintext);
                return BASE64.encodeToStr(ciphertext);
            } catch (Exception e) {
                throw CryptoException.of(algorithm+"加密异常", e);
            }
        }
        /**
         * 解密
         * @param data 密文
         * @param prikey 私钥
         * @param cryptoType 加密类型
         * @return 明文
         */
        public static String decrypt(String data, String prikey, CryptoType cryptoType) {
            String algorithm = cryptoType.getAlgorithm();
            try {
                byte[] ciphertext = BASE64.decodeToBytes(data);
                KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
                KeySpec keySpec = new PKCS8EncodedKeySpec(BASE64.decodeToBytes(prikey));
                PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
                Cipher decryptCipher = Cipher.getInstance(cryptoType.getCipher());
                decryptCipher.init(Cipher.DECRYPT_MODE, privateKey, new SecureRandom());
                byte[] plaintext = decryptCipher.doFinal(ciphertext);
                return BASE64.bytesToStr(plaintext);
            } catch (Exception e) {
                throw CryptoException.of(algorithm+"解密异常", e);
            }
        }
        /**
         * 数字签名
         * @param data 数据
         * @param priKey 私钥
         * @return 签名
         */
        public static String sign(String data, String priKey, CryptoType cryptoType){
            String algorithm = cryptoType.getAlgorithm();
            try {
                byte[] plaintext = BASE64.encodeToBytes(data);
                KeySpec keySpec = new PKCS8EncodedKeySpec(BASE64.decodeToBytes(priKey));
                KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
                PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
                Signature signature = Signature.getInstance(cryptoType.getCipher());
                signature.initSign(privateKey);
                signature.update(plaintext);
                byte[] sign = signature.sign();
                return BASE64.encodeToStr(sign);
            } catch (Exception e) {
                throw CryptoException.of(algorithm+"签名异常", e);
            }
        }
        /**
         * 验签
         * @param data 数据
         * @param pubKey 公钥
         * @param sign 签名
         * @param cryptoType 加密类型
         * @return 是否验证通过
         */
        public static boolean verify(String data, String pubKey, String sign, CryptoType cryptoType){
            String algorithm = cryptoType.getAlgorithm();
            try {
                byte[] plaintext = BASE64.encodeToBytes(data);
                KeySpec keySpec = new X509EncodedKeySpec(BASE64.decodeToBytes(pubKey));
                KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
                PublicKey publicKey = keyFactory.generatePublic(keySpec);
                Signature signature = Signature.getInstance(cryptoType.getCipher());
                signature.initVerify(publicKey);
                signature.update(plaintext);
                return signature.verify(BASE64.decodeToBytes(sign));
            } catch (Exception e) {
                logger.info("{}签名异常:{}", algorithm, e.getMessage(), e);
                return false;
            }
        }
    }

    /**
     * 哈希算法
     */
    private static class HashAlg {
        private static final char[] HEX_CHARS = new char[] {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
        };
        /**
         * 哈希计算
         * @param data 数据
         * @param cryptoType 算法类型
         * @return 计算结果
         */
        public static String digest(String data, CryptoType cryptoType){
            String algorithm = cryptoType.getAlgorithm();
            try {
                MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
                byte[] digest =  messageDigest.digest(BASE64.strToBytes(data));
                return toHexString(digest);
            } catch (NoSuchAlgorithmException e) {
                throw CryptoException.of(algorithm+"计算异常", e);
            }
        }
        /**
         * 转十六进制字符串
         * @param bytes 二进制结果
         * @return 字符串
         */
        public static String toHexString(byte[] bytes) {
            StringBuilder result = new StringBuilder();
            for (byte b : bytes) {
                result.append(HEX_CHARS[b >>> 4 & 15]);
                result.append(HEX_CHARS[b & 15]);
            }
            return result.toString();
        }
    }

    /**
     * AES (Advanced Encryption Standard)
     * 对称加密
     * 是目前最流行的对称加密算法之一,支持128、192和256位的密钥长度
     */
    public static class AES {
        /**
         * 生成密钥
         * @return 密钥
         */
        public static String generateKey() {
            return SymCrypto.generateKey(CryptoType.AES, 128);
        }
        /**
         * 加密
         * @param data 数据
         * @param key 密钥
         * @return 加密结果
         */
        public static String encrypt(String data, String key) {
            return SymCrypto.encrypt(data, key, CryptoType.AES);
        }
        /**
         * 解密
         * @param data 已加密数据
         * @param key 密钥
         * @return 解密结果
         */
        public static String decrypt(String data, String key) {
            return SymCrypto.decrypt(data, key, CryptoType.AES);
        }
    }

    /**
     * DES (Data Encryption Standard)
     * 对称加密
     * 使用56位的密钥进行加密,已被证实可以在短时间内破解
     */
    public static class DES {
        /**
         * 生成密钥
         * @return 密钥
         */
        public static String generateKey() {
            return SymCrypto.generateKey(CryptoType.DES, 56);
        }
        /**
         * 加密
         * @param data 数据
         * @param key 密钥
         * @return 加密结果
         */
        public static String encrypt(String data, String key) {
            return SymCrypto.encrypt(data, key, CryptoType.DES);
        }
        /**
         * 解密
         * @param data 已加密数据
         * @param key 密钥
         * @return 解密结果
         */
        public static String decrypt(String data, String key) {
            return SymCrypto.decrypt(data, key, CryptoType.DES);
        }
    }

    /**
     * 3DES (Triple DES)
     * 对称加密
     * 是DES的改进版,使用168位的密钥进行加密
     */
    public static class DES3 {
        /**
         * 生成密钥
         * @return 密钥
         */
        public static String generateKey() {
            return SymCrypto.generateKey(CryptoType.DES3, 168);
        }
        /**
         * 加密
         * @param data 数据
         * @param key 密钥
         * @return 加密结果
         */
        public static String encrypt(String data, String key) {
            return SymCrypto.encrypt(data, key, CryptoType.DES3);
        }
        /**
         * 解密
         * @param data 已加密数据
         * @param key 密钥
         * @return 解密结果
         */
        public static String decrypt(String data, String key) {
            return SymCrypto.decrypt(data, key, CryptoType.DES3);
        }
    }

    /**
     * RC4 (Rivest Cipher 4)
     * 对称加密
     * 速度较快,但安全性较低,已被认为不够安全。
     */
    public static class RC4 {
        /**
         * 生成密钥
         * @return 密钥
         */
        public static String generateKey() {
            return SymCrypto.generateKey(CryptoType.RC4);
        }
        /**
         * 加密
         * @param data 数据
         * @param key 密钥
         * @return 加密结果
         */
        public static String encrypt(String data, String key) {
            return SymCrypto.encrypt(data, key, CryptoType.RC4);
        }
        /**
         * 解密
         * @param data 已加密数据
         * @param key 密钥
         * @return 解密结果
         */
        public static String decrypt(String data, String key) {
            return SymCrypto.decrypt(data, key, CryptoType.RC4);
        }
    }

    /**
     * SM4 (国密)
     * 对称加密
     * 由我国国家密码管理局发布,常用于无线互联网加密等领域
     */
    public static class SM4 {
        //TODO...
        //JDK暂未提供实现
    }

    /**
     * RSA (Rivest, Shamir, Adleman)
     * 非对称加密
     * 基于大数分解的困难性,经历了各种攻击但未被完全攻破
     */
    public static class RSA {
        /**
         * 生成密钥对
         * @return 密钥对
         */
        public static StrKeyPair generateKeyPair() {
            //密匙长度通常为1024或2048
            //可取值512、1024、2048和4096,最小512
            return AsymCrypto.generateKeyPair(CryptoType.RSA, 512);
        }
        /**
         * 加密
         * @param data 数据
         * @param publicKey 公钥
         * @return 加密结果
         */
        public static String encrypt(String data, String publicKey) {
            return AsymCrypto.encrypt(data, publicKey, CryptoType.RSA);
        }
        /**
         * 解密
         * @param data 已加密数据
         * @param privateKey 私钥
         * @return 解密结果
         */
        public static String decrypt(String data, String privateKey) {
            return AsymCrypto.decrypt(data, privateKey, CryptoType.RSA);
        }
    }

    /**
     * ECC (Elliptic Curve Cryptography)
     * 非对称加密
     * 使用椭圆曲线数学进行加密,安全性较高
     */
    public static class ECC {
        //TODO...
        //JDK暂未提供实现,依赖于BouncyCastle实现
    }

    /**
     * DSA (Digital Signature Algorithm)
     * 非对称加密
     * 用于数字签名,确保信息的完整性和来源的真实性
     */
    public static class DSA {
        /**
         * 生成密钥对
         * @return 密钥对
         */
        public static StrKeyPair generateKeyPair() {
            return AsymCrypto.generateKeyPair(CryptoType.DSA, 1024);
        }
        /**
         * 签名
         * @param data 数据
         * @param privateKey 私钥
         * @return 加密结果
         */
        public static String sign(String data, String privateKey) {
            return AsymCrypto.sign(data, privateKey, CryptoType.DSA);
        }
        /**
         * 验签
         * @param data 数据(未加密)
         * @param publicKey 公钥
         * @return 是否验证通过
         */
        public static boolean verify(String data, String publicKey, String sign) {
            return AsymCrypto.verify(data, publicKey, sign, CryptoType.DSA);
        }
    }

    /**
     * SM2 (国密)
     * 非对称加密
     * 中国的国家密码标准,类似于RSA。‌
     */
    public static class SM2 {
        //TODO...
        //JDK暂未提供实现
    }

    /**
     * DH (Diffie-Hellman)
     * 非对称加密
     * 用于密钥交换,不直接用于加密和解密
     * 是一种确保共享KEY安全穿越不安全网络的方法,也就是常说的密钥一致协议
     * 由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想
     * 简单的说就是允许两名用户在公开媒体上交换信息以生成“一致”的、可以共享的密钥
     * 也就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)
     * DH算法的通信模型:
     *   1.甲方将自己的公钥发给乙方
     *   2.乙方根据甲方发来的公钥,生成自己的公钥和私钥
     *   3.乙方将自己的公钥发送给甲方
     *   4.甲方和乙方,生成一样的秘钥。用于加密数据
     */
    public static class DH {
        static {
            System.getProperties().setProperty("jdk.crypto.KeyAgreement.legacyKDF", "true");
        }
        /**
         * 甲方初始化一对密钥
         * @return 密钥对
         */
        public static StrKeyPair initKeyPair() {
            return AsymCrypto.generateKeyPair(CryptoType.DH, 512);
        }
        /**
         * 乙方根据甲方公钥初始化一对密钥
         * @return 密钥对
         */
        public static StrKeyPair initKeyPair(String pubKey) {
            String algorithm = CryptoType.DH.getAlgorithm();
            try {
                //读取公钥信息
                KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(BASE64.decodeToBytes(pubKey));
                DHPublicKey publicKey = (DHPublicKey) keyFactory.generatePublic(keySpec);
                //根据公钥生成一对新的密钥
                KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm);
                generator.initialize(publicKey.getParams());
                KeyPair keyPair = generator.generateKeyPair();
                return StrKeyPair.of(keyPair);
            } catch (Exception e) {
                throw CryptoException.of(algorithm+"pubKey生成密匙对异常", e);
            }
        }
        /**
         * 根据对方的公钥和自己的私钥生成本地密钥
         * @param pubKey 公钥
         * @param priKey 私钥
         * @param cryptoType 加密类型
         * @return 本地密钥
         */
        private static SecretKey getSecretKey(String pubKey, String priKey, CryptoType cryptoType) {
            try {
                String algorithm = CryptoType.DH.getAlgorithm();
                if(CryptoType.DH.equals(cryptoType)){
                    throw CryptoException.of("DH生成本地密钥不能使用相同算法");
                }
                KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
                X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(BASE64.decodeToBytes(pubKey));
                PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(BASE64.decodeToBytes(priKey));
                PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
                PrivateKey privateKey = keyFactory.generatePrivate(priKeySpec);
                KeyAgreement agreement = KeyAgreement.getInstance(algorithm);
                agreement.init(privateKey);
                agreement.doPhase(publicKey, true);
                return agreement.generateSecret(cryptoType.getAlgorithm());
            } catch (Exception e) {
                throw CryptoException.of("DH生成本地密钥异常", e);
            }
        }
        /**
         * 获得AES密钥
         * @param pubKey 对方的公钥
         * @param priKey 自己的私钥
         * @param cryptoType 加密类型
         * @return AES密钥
         */
        public static String getKey(String pubKey, String priKey, CryptoType cryptoType){
            SecretKey secretKey = getSecretKey(pubKey, priKey, cryptoType);
            return BASE64.encodeToStr(secretKey.getEncoded());
        }
        /**
         * 加密
         * @param data 明文
         * @param pubKey 甲方公钥
         * @param priKey 乙方私钥
         * @param cryptoType 加密类型
         * @return 密文
         */
        public static String encrypt(String data, String pubKey, String priKey, CryptoType cryptoType) {
            try {
                SecretKey secretKey = getSecretKey(pubKey, priKey, cryptoType);
                Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
                cipher.init(Cipher.ENCRYPT_MODE, secretKey);
                byte[] bytes = cipher.doFinal(BASE64.strToBytes(data));
                return BASE64.encodeToStr(bytes);
            } catch (Exception e) {
                throw CryptoException.of("DH加密异常", e);
            }
        }
        /**
         * 解密
         * @param data 密文
         * @param pubKey 乙方公钥
         * @param priKey 甲方私钥
         * @param cryptoType 加密类型
         * @return 明文
         */
        public static String decrypt(String data, String pubKey, String priKey, CryptoType cryptoType) {
            try {
                SecretKey secretKey = getSecretKey(pubKey, priKey, cryptoType);
                Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
                cipher.init(Cipher.DECRYPT_MODE, secretKey);
                byte[] bytes = cipher.doFinal(BASE64.decodeToBytes(data));
                return BASE64.bytesToStr(bytes);
            } catch (Exception e) {
                throw CryptoException.of("DH解密异常", e);
            }
        }
    }

    /**
     * MD5 (Message Digest Algorithm 5)
     * 是一种广泛使用的哈希算法,生成的哈希值为 128 位(16 字节)
     * 常用于校验数据的完整性,但由于其存在安全性漏洞,已不适合用于密码存储等安全场景
     */
    public static class MD5 {
        /**
         * 计算Hash值
         * @param data 数据
         * @return hash值
         */
        public static String hash(String data) {
            return HashAlg.digest(data, CryptoType.MD5);
        }
        /**
         * 验证哈希值
         * @param data 数据
         * @param md5 md5哈希值
         * @return 是否验证成功
         */
        public static boolean verify(String data, String md5) {
            return equalsNoEarlyReturn(md5, hash(data));
        }
    }

    /**
     * SHA-1 (Secure Hash Algorithm 1)
     * SHA-1 是一种产生 160 位(20 字节)哈希值的算法
     * 然而,SHA-1也被证明存在安全性问题,因此在对数据的完整性和安全性要求较高的场景中,不再推荐使用
     */
    public static class SHA1 {
        /**
         * 计算Hash值
         * @param data 数据
         * @return hash值
         */
        public static String hash(String data) {
            return HashAlg.digest(data, CryptoType.SHA1);
        }
        /**
         * 验证哈希值
         * @param data 数据
         * @param sha1 sha1哈希值
         * @return 是否验证成功
         */
        public static boolean verify(String data, String sha1) {
            return equalsNoEarlyReturn(sha1, hash(data));
        }
    }

    /**
     * SHA-256 (Secure Hash Algorithm 256-bit)
     * SHA-256 是 SHA-2 系列中的一种哈希算法,生成的哈希值长度为 256 位(32 字节)
     * 具有更高的安全性,SHA-256 在许多领域中被广泛使用,包括密码学、数字证书等
     */
    public static class SHA256 {
        /**
         * 计算Hash值
         * @param data 数据
         * @return hash值
         */
        public static String hash(String data) {
            return HashAlg.digest(data, CryptoType.SHA256);
        }
        /**
         * 验证哈希值
         * @param data 数据
         * @param sha256 sha256哈希值
         * @return 是否验证成功
         */
        public static boolean verify(String data, String sha256) {
            return equalsNoEarlyReturn(sha256, hash(data));
        }
    }

	/**
     * SHA-512 (Secure Hash Algorithm 512-bit)
     */
    public static class SHA512 {
        /**
         * 计算Hash值
         * @param data 数据
         * @return hash值
         */
        public static String hash(String data) {
            return HashAlg.digest(data, CryptoType.SHA512);
        }
        /**
         * 验证哈希值
         * @param data 数据
         * @param sha512 sha512哈希值
         * @return 是否验证成功
         */
        public static boolean verify(String data, String sha512) {
            return equalsNoEarlyReturn(sha512, hash(data));
        }
    }

    /**
     * HMAC(Hash Message Authentication Code)
     * 散列消息鉴别码,基于密钥的Hash算法的认证协议
     * 消息鉴别码实现鉴别的原理是用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性
     * 使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输,接收方利用与发送方共享的密钥进行鉴别认证等
     * 算法可以与许多哈希函数结合使用,常用的哈希函数包括:
	 * HMAC-MD5:使用MD5哈希函数生成HMAC
	 * HMAC-SHA1:使用SHA-1哈希函数生成HMAC
	 * HMAC-SHA256:使用SHA-256哈希函数生成HMAC
	 * HMAC-SHA512:使用SHA-512哈希函数生成HMAC
     */
    public static class HMAC {
        /**
         * 计算Hash值
         * @param data 数据
         * @return hash值
         */
        public static String hash(String data, String key) {
            try{
                String algorithm = CryptoType.HMAC.getAlgorithm();
                Mac mac = Mac.getInstance(algorithm);
                mac.init(CryptoType.HMAC.getSecretKey(BASE64.strToBytes(key)));
                byte[] bytes = mac.doFinal(BASE64.strToBytes(data));
                return HashAlg.toHexString(bytes);
            }catch (Exception e) {
                throw CryptoException.of("HMC计算异常", e);
            }
        }
    }

    @Data
    @Builder
    public static class StrKeyPair {
        private String publicKey;
        private String privateKey;
        public static StrKeyPair of(KeyPair keyPair){
            String publicKey = BASE64.encodeToStr(keyPair.getPublic().getEncoded());
            String privateKey = BASE64.encodeToStr(keyPair.getPrivate().getEncoded());
            return StrKeyPair.builder().publicKey(publicKey).privateKey(privateKey).build();
        }
    }

    /**
     * 更安全的字符串比对(可防止时间序列攻击)
     * 来自org.springframework.security.crypto.bcrypt.BCrypt
     * @param a 字符串a
     * @param b 字符串b
     * @return 是否相同
     */
    private static boolean equalsNoEarlyReturn(String a, String b) {
        char[] caa = a.toCharArray(), cab = b.toCharArray();
        if (caa.length != cab.length) {
            return false;
        }
        byte ret = 0;
        for(int i = 0; i < caa.length; ++i) {
            ret = (byte)(ret | caa[i] ^ cab[i]);
        }
        return ret == 0;
    }

    @Getter
    @AllArgsConstructor
    public enum CryptoType {
        AES("AES", "AES/CBC/PKCS5Padding", CryptoType::getAESKeySpec),
        DES("DES", "DES/ECB/PKCS5Padding", CryptoType::getDESKeySpec),
        DES3("DESede", "DESede", CryptoType::getDESedeKeySpec),
        RC4("RC4", "RC4", CryptoType::getRC4KeySpec),
        RSA("RSA", "RSA", null),
        DSA("DSA", "SHA256withDSA", null),
        DH("DH", "DH", null),
        MD5("MD5", null, null),
        SHA1("SHA-1", null, null),
        SHA256("SHA-256", null, null),
        SHA512("SHA-512", null, null),
        HMAC("HmacSHA256", null, CryptoType::getHMacKeySpec);

        private final String algorithm;
        private final String cipher;
        private final Function<byte[], SecretKey> keyCreator;

        public SecretKey getSecretKey(byte[] key){
            return keyCreator==null ? null : keyCreator.apply(key);
        }
        public SecretKey getSecretKey(KeySpec keySpec) throws NoSuchAlgorithmException, InvalidKeySpecException {
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(getAlgorithm());
            return keyFactory.generateSecret(keySpec);
        }
        private static SecretKey getAESKeySpec(byte[] key){
            return new SecretKeySpec(key, AES.getAlgorithm());
        }
        private static SecretKey getRC4KeySpec(byte[] key){
            return new SecretKeySpec(key, RC4.getAlgorithm());
        }
        private static SecretKey getHMacKeySpec(byte[] key){
            return new SecretKeySpec(key, HMAC.getAlgorithm());
        }
        private static SecretKey getDESKeySpec(byte[] key){
            try {
                return DES.getSecretKey(new DESKeySpec(key));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        private static SecretKey getDESedeKeySpec(byte[] key){
            try {
                return DES3.getSecretKey(new DESedeKeySpec(key));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static class CryptoException extends RuntimeException{
        public CryptoException(String message) {
            super(message);
        }
        public CryptoException(String message, Throwable cause) {
            super(message, cause);
        }
        public static CryptoException of(String prefix, Exception e){
            return new CryptoException(prefix+":"+e.getMessage(), e.getCause());
        }
        public static CryptoException of(String message){
            return new CryptoException(message);
        }
    }
}

2.测试

package com.visy.utils;

/**
 * 密码工具测试
 * @author visy.wang
 * @date 2024/9/5 22:57
 */
public class CryptoUtilTest {
    public static void main(String[] args) {
        testBase64("我是你爸爸");
        System.out.println("-----------------------------");
        String key = CryptoUtil.AES.generateKey();
        testAes("我是你爸爸", key);
        System.out.println("-----------------------------");
        testAes("我是你爸爸", key);
        System.out.println("-----------------------------");
        testDes("我是你爸爸");
        System.out.println("-----------------------------");
        testDes3("我是你爸爸");
        System.out.println("-----------------------------");
        testRc4("我是你爸爸");
        System.out.println("-----------------------------");
        testRsa("我是你爸爸");
        System.out.println("-----------------------------");
        testDsa("我是你爸爸");
        System.out.println("-----------------------------");
        testDh("我是你爸爸");
        System.out.println("-----------------------------");
        testMd5("我是你爸爸");
        System.out.println("-----------------------------");
        testSha1("我是你爸爸");
        System.out.println("-----------------------------");
        testSha256("我是你爸爸");
        System.out.println("-----------------------------");
        testSha512("我是你爸爸");
        System.out.println("-----------------------------");
        testHmac("我是你爸爸");
    }

    private static void testBase64(String data){
        System.out.println("BASE64明文: "+ data);
        String encode = CryptoUtil.BASE64.encode(data);
        System.out.println("BASE64编码: "+ encode);
        String decode = CryptoUtil.BASE64.decode(encode);
        System.out.println("BASE64解码: "+ decode);
    }

    private static void testAes(String data, String key){
        System.out.println("AES密匙: "+ key);
        System.out.println("AES明文: "+ data);
        String encrypt = CryptoUtil.AES.encrypt(data, key);
        System.out.println("AES加密: "+ encrypt);
        String decrypt = CryptoUtil.AES.decrypt(encrypt, key);
        System.out.println("AES解密: "+ decrypt);
    }
    private static void testDes(String data){
        String key = CryptoUtil.DES.generateKey();
        System.out.println("DES密匙: "+ key);
        System.out.println("DES明文: "+ data);
        String encrypt = CryptoUtil.DES.encrypt(data, key);
        System.out.println("DES加密: "+ encrypt);
        String decrypt = CryptoUtil.DES.decrypt(encrypt, key);
        System.out.println("DES解密: "+ decrypt);
    }
    private static void testDes3(String data){
        String key = CryptoUtil.DES3.generateKey();
        System.out.println("DES3密匙: "+ key);
        System.out.println("DES3明文: "+ data);
        String encrypt = CryptoUtil.DES3.encrypt(data, key);
        System.out.println("DES3加密: "+ encrypt);
        String decrypt = CryptoUtil.DES3.decrypt(encrypt, key);
        System.out.println("DES3解密: "+ decrypt);
    }
    private static void testRc4(String data){
        String key = CryptoUtil.RC4.generateKey();
        System.out.println("RC4密匙: "+ key);
        System.out.println("RC4明文: "+ data);
        String encrypt = CryptoUtil.RC4.encrypt(data, key);
        System.out.println("RC4加密: "+ encrypt);
        String decrypt = CryptoUtil.RC4.decrypt(encrypt, key);
        System.out.println("RC4解密: "+ decrypt);
    }
    private static void testRsa(String data){
        CryptoUtil.StrKeyPair keyPair = CryptoUtil.RSA.generateKeyPair();
        System.out.println("RSA密匙(公钥): "+ keyPair.getPublicKey());
        System.out.println("RSA密匙(私钥): "+ keyPair.getPrivateKey());
        System.out.println("RSA明文: "+ data);
        String encrypt = CryptoUtil.RSA.encrypt(data, keyPair.getPublicKey());
        System.out.println("RSA加密: "+ encrypt);
        String decrypt = CryptoUtil.RSA.decrypt(encrypt, keyPair.getPrivateKey());
        System.out.println("RSA解密: "+ decrypt);
    }
    private static void testDsa(String data){
        CryptoUtil.StrKeyPair keyPair = CryptoUtil.DSA.generateKeyPair();
        System.out.println("DSA密匙(公钥): "+ keyPair.getPublicKey());
        System.out.println("DSA密匙(私钥): "+ keyPair.getPrivateKey());
        System.out.println("DSA明文: "+ data);
        String sign = CryptoUtil.DSA.sign(data, keyPair.getPrivateKey());
        System.out.println("DSA签名: "+ sign);
        boolean verify = CryptoUtil.DSA.verify(data, keyPair.getPublicKey(), sign);
        System.out.println("DSA验签结果: "+ verify);
    }
    private static void testDh(String data){
        //1.甲方生成一对密钥
        CryptoUtil.StrKeyPair keyPair1 = CryptoUtil.DH.initKeyPair();
        System.out.println("DH公钥(甲方): "+ keyPair1.getPublicKey());
        System.out.println("DH私钥(甲方): "+ keyPair1.getPrivateKey());
        //2.甲方将自己的公钥通过互联网分享给乙方
        //3.乙方根据甲方的公钥生成一对自己的密钥
        CryptoUtil.StrKeyPair keyPair2 = CryptoUtil.DH.initKeyPair(keyPair1.getPublicKey());
        System.out.println("DH公钥(乙方): "+ keyPair2.getPublicKey());
        System.out.println("DH私钥(乙方): "+ keyPair2.getPrivateKey());
        //对比他们的密钥,发现是不一样的
        System.out.println("DH公钥-甲乙比对: "+ keyPair1.getPublicKey().equals(keyPair2.getPublicKey()));
        System.out.println("DH私钥-甲乙比对: "+ keyPair1.getPrivateKey().equals(keyPair2.getPrivateKey()));
        CryptoUtil.CryptoType cryptoType = CryptoUtil.CryptoType.AES;
        //4.乙方通过甲方的公钥+自己的私钥获得一个密钥(对称加密)
        String key2 = CryptoUtil.DH.getKey(keyPair1.getPublicKey(), keyPair2.getPrivateKey(), cryptoType);
        System.out.println("DH乙方获得密钥: "+ key2);
        //5.乙方将自己的公钥通过互联网分享给甲方
        //6.甲方通过乙方的公钥+自己的私钥获得一个密钥(对称加密,和乙方获得的密钥是同一个)
        String key1 = CryptoUtil.DH.getKey(keyPair2.getPublicKey(), keyPair1.getPrivateKey(), cryptoType);
        System.out.println("DH甲方获得密钥: "+ key1);
        System.out.println("DH甲乙方获得密钥对比: "+ key1.equals(key2));
        //7.至此,密钥交换完成,后续通讯使用密钥(对称加密)加解密数据
        //Tips: 后续完全可以不用DH中的加密解密函数,直接使用对应的对称加密类处理
        System.out.println("DH明文: "+ data);
        String encrypt = CryptoUtil.DH.encrypt(data, keyPair1.getPublicKey(), keyPair2.getPrivateKey(), cryptoType);
        System.out.println("DH乙方加密: "+ encrypt);
        String decrypt = CryptoUtil.DH.decrypt(encrypt, keyPair2.getPublicKey(), keyPair1.getPrivateKey(), cryptoType);
        System.out.println("DH甲方解密: "+ decrypt);
    }
    private static void testMd5(String data){
        System.out.println("MD5明文: "+ data);
        String hash = CryptoUtil.MD5.hash(data);
        System.out.println("MD5哈希值: "+ hash);
        boolean verify = CryptoUtil.MD5.verify(data, hash);
        System.out.println("MD5哈希值验证: "+ verify);
    }
    private static void testSha1(String data){
        System.out.println("SHA1明文: "+ data);
        String hash = CryptoUtil.SHA1.hash(data);
        System.out.println("SHA1哈希值: "+ hash);
        boolean verify = CryptoUtil.SHA1.verify(data, hash);
        System.out.println("SHA1哈希值验证: "+ verify);
    }
    private static void testSha256(String data){
        System.out.println("SHA256明文: "+ data);
        String hash = CryptoUtil.SHA256.hash(data);
        System.out.println("SHA256哈希值: "+ hash);
        boolean verify = CryptoUtil.SHA256.verify(data, hash);
        System.out.println("SHA256哈希值验证: "+ verify);
    }
    private static void testSha512(String data){
        System.out.println("SHA512明文: "+ data);
        String hash = CryptoUtil.SHA512.hash(data);
        System.out.println("SHA512哈希值: "+ hash);
        boolean verify = CryptoUtil.SHA512.verify(data, hash);
        System.out.println("SHA512哈希值验证: "+ verify);
    }
    private static void testHmac(String data){
        System.out.println("HMAC明文: "+ data);
        String hash = CryptoUtil.HMAC.hash(data, "ssssssssssss");
        System.out.println("HMAC哈希值: "+ hash);
    }
}

3.测试输出

BASE64明文: 我是你爸爸
BASE64编码: 5oiR5piv5L2g54i454i4
BASE64解码: 我是你爸爸
-----------------------------
AES密匙: LFI5urSZxTN62YS9iJDDEg==
AES明文: 我是你爸爸
AES加密: HgvWovqonfcS4STWaFa2+z2WbYzCWFe4cnMBMFDQOjg=
AES解密: 我是你爸爸
-----------------------------
AES密匙: LFI5urSZxTN62YS9iJDDEg==
AES明文: 我是你爸爸
AES加密: PBSRjTpHSfCQQRZzFIJgpciwvVoqzvrkRCRj4h5z6AQ=
AES解密: 我是你爸爸
-----------------------------
DES密匙: YQILv6JSIOw=
DES明文: 我是你爸爸
DES加密: VRpgS3I+0gacG41MczwP/w==
DES解密: 我是你爸爸
-----------------------------
DES3密匙: /fhtL6H05m5J02vC/quzoZffxPTBZPHc
DES3明文: 我是你爸爸
DES3加密: 4iWYI3ZoG3w2vr628DOYwA==
DES3解密: 我是你爸爸
-----------------------------
RC4密匙: 40wd7An+cDCmBrkip7QH5A==
RC4明文: 我是你爸爸
RC4加密: tL4d73aO9WojzIFJ9mwo
RC4解密: 我是你爸爸
-----------------------------
RSA密匙(公钥): MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKDGdC1i8qoRWEewVXxxhf736/QS+AaQa0mlLM8D6aXYvxw/RqncF263OmPhCPRX168mTehgotOsE0rknPvyK0MCAwEAAQ==
RSA密匙(私钥): MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAoMZ0LWLyqhFYR7BVfHGF/vfr9BL4BpBrSaUszwPppdi/HD9GqdwXbrc6Y+EI9FfXryZN6GCi06wTSuSc+/IrQwIDAQABAkB7Nju4wLj57tr57cBF43ZuZS+12Iet+CXQxb4mVHhOOSkEOBV9q9tP/WZT/vV/6WNToTKZjfxsIH2HpIwFf2kRAiEA5uoy6KLDb3daL3r05pczF+Xl8/i6qun/ChZdBDjm+ssCIQCyPadgJO16nlRUgmn1Mw11n6/vX4K1AMlU3YW87jAqaQIhAILx1CSwB/uxxuad5zrMCyFGMXyEU/aP8xyZSe4XBoS5AiACtMLsx8K/QNYg7lXzfhHvPjxqkvWmD9v+qNpV8vvSOQIgAYYXHSbe/N8zTzGLhUTDSe7IJd2q0E2V16QWFO4V61A=
RSA明文: 我是你爸爸
RSA加密: Ncvg9PfkanfOU82AChVWSfzbrFYM8IpzZMXCkNg2fo9+66I3kUNAI9wo6sSCWvfhOgEyMCghR1qXLorWYDFbdg==
RSA解密: 我是你爸爸
-----------------------------
DSA密匙(公钥): MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAcsToEqCe7xIHH1oD7gIQmtF+oBU+uXcluiM0aob5RdPmyGF6YeVw+u0BsYMXnjq6fxj75e50TIdExvSCPP2AAMtrkMHjXR4BSH/Yl0zoHJwq5VBnZClms4GAQgGhbuzVWN6VUFwG4pMOGF4yLd7G2WdzvzWHYtSa6nh0gHA4mmE=
DSA密匙(私钥): MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUPrGLaMsNFIni0gzod1OW57YpeBM=
DSA明文: 我是你爸爸
DSA签名: MCwCFF2mbmI51645C4CkB0KWliyUMeREAhRmkgOL84uTI2RwqmS0r+IYK1rJ/w==
DSA验签结果: true
-----------------------------
DH公钥(甲方): MIHfMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgANDAAJAL2sxbrYvYzGDYMM9ERNQfB/hI+GdsJfGxUsMKCjx4wOsSXJ8SAOrjprzoSepI3xHZX3Ar+vPe0FFi5dOAzlZCQ==
DH私钥(甲方): MIHSAgEAMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgAQzAjEAyXjFRjASU1Rbb4llKMClgN0oZU1QmSNhH/1ru7gmNAfPObnygxlmUP7mYAx2K3ng
DH公钥(乙方): MIHfMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgANDAAJALvJdwbNIqbzgZ4HQo6r3JtY3hsIMY8IAiZ7qvZMk6b3iamBRF/JksFjI2OFExl25tmNa9ELW2hH2bYrrMR6NLA==
DH私钥(乙方): MIHSAgEAMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgAQzAjEA7Z31W/4C4QYjHB/SzgHTkSwmffX9JOk1D+DPukOBBG7Bj8VszrMxiy1I3WcAxnMm
DH公钥-甲乙比对: false
DH私钥-甲乙比对: false
DH乙方获得密钥: Q8HdDfsI0UmdZVxRaeoSTJZmphYhgf3ITx6lN9po0m4=
DH甲方获得密钥: Q8HdDfsI0UmdZVxRaeoSTJZmphYhgf3ITx6lN9po0m4=
DH甲乙方获得密钥对比: true
DH明文: 我是你爸爸
DH乙方加密: ogodF+JfdRdwZZNP4OVdIw==
DH甲方解密: 我是你爸爸
-----------------------------
MD5明文: 我是你爸爸
MD5哈希值: 1d3ecc8cb56a34ee485fe33b3b54245e
MD5哈希值验证: true
-----------------------------
SHA1明文: 我是你爸爸
SHA1哈希值: fcee7799065b1edaf6e655a89c2d365ea6fa5fbd
SHA1哈希值验证: true
-----------------------------
SHA256明文: 我是你爸爸
SHA256哈希值: 83987ab0fb9c65ad4b6984f7f83063863b2d6b2957b09e55cb0d0173d1b03ac1
SHA256哈希值验证: true
-----------------------------
SHA512明文: 我是你爸爸
SHA512哈希值: 717e952878f60ba00fd4d2f185050be5e7277823e4cdae6a115167f7369532a53671eb6bb748d9233f3ce995679f8c89ea5e4a9d118e17aba33183a69632d9c1
SHA512哈希值验证: true
-----------------------------
HMAC明文: 我是你爸爸
HMAC哈希值: c8dc58c385bf5f892a5a7b26073731aaee86294d2b7f03250ab13bc4206f1fa6

4.该项目已上传maven中央仓库,欢迎使用

4.1引入依赖
<dependency>
    <groupId>io.github.xhom</groupId>
    <artifactId>hom-crypt</artifactId>
    <version>1.0.0</version>
</dependency>
4.2使用示例
package com.visy.utils;

import io.github.xhom.crypt.comm.StrKeyPair;
import io.github.xhom.crypt.util.BASE64;
import io.github.xhom.crypt.util.CryptUtil;

/**
 * @author visy.wang
 * @date 2024/9/9 18:20
 */
public class CryptUtilTest {
    public static void main(String[] args) {
        testBase64("我是你爸爸");
        System.out.println("-----------------------------");
        testAes("我是你爸爸");
        System.out.println("-----------------------------");
        testRsa("我是你爸爸");
        System.out.println("-----------------------------");
        testMd5("我是你爸爸");
    }

    private static void testBase64(String data){
        System.out.println("BASE64明文: "+ data);
        String encode = BASE64.encode(data);
        System.out.println("BASE64编码: "+ encode);
        String decode = BASE64.decode(encode);
        System.out.println("BASE64解码: "+ decode);
    }

    private static void testAes(String data){
        String key = CryptUtil.AES.generateKey();
        System.out.println("AES密匙: "+ key);
        System.out.println("AES明文: "+ data);
        String encrypt = CryptUtil.AES.encrypt(data, key);
        System.out.println("AES加密: "+ encrypt);
        String decrypt = CryptUtil.AES.decrypt(encrypt, key);
        System.out.println("AES解密: "+ decrypt);
    }

    private static void testRsa(String data){
        StrKeyPair keyPair = CryptUtil.RSA.generateKeyPair();
        System.out.println("RSA密匙(公钥): "+ keyPair.getPublicKey());
        System.out.println("RSA密匙(私钥): "+ keyPair.getPrivateKey());
        System.out.println("RSA明文: "+ data);
        String encrypt = CryptUtil.RSA.encrypt(data, keyPair.getPublicKey());
        System.out.println("RSA加密: "+ encrypt);
        String decrypt = CryptUtil.RSA.decrypt(encrypt, keyPair.getPrivateKey());
        System.out.println("RSA解密: "+ decrypt);
    }

    private static void testMd5(String data){
        System.out.println("MD5明文: "+ data);
        String hash = CryptUtil.MD5.hash(data);
        System.out.println("MD5值: "+ hash);
    }
}
4.3输出
BASE64明文: 我是你爸爸
BASE64编码: 5oiR5piv5L2g54i454i4
BASE64解码: 我是你爸爸
-----------------------------
AES密匙: fkjjNiAlEiyE6VlvlkXF8Q==
AES明文: 我是你爸爸
AES加密: h2Eazl3hAigo4gkHRBuSQKT9Q8oeZjXxMJhqOquWWOQ=
AES解密: 我是你爸爸
-----------------------------
RSA密匙(公钥): MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMA+Hru+5WAyT91sCxSyzogs+qFqoZwrrRNqnP3hir4wZKQhRWQc9Jp1F8+YrbacsL/NUPVESGH7qQbHgkBuyYkCAwEAAQ==
RSA密匙(私钥): MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAwD4eu77lYDJP3WwLFLLOiCz6oWqhnCutE2qc/eGKvjBkpCFFZBz0mnUXz5ittpywv81Q9URIYfupBseCQG7JiQIDAQABAkEAueyaXquOPY4LLbOrt9YC5zLRJsHxERAwsKGgue2i+LI4x5EyuOgsDAV7brYqY4+C60Osf82vg59cqa96NvTAXQIhAO4DVckjDW6pYLWLNNVHB7DnviCbarVjmkQ71YHGHXgTAiEAzsVMgxmHJxcsOU/A0DWsEV+2dmJc/OKjMefupVqD43MCIHmDpGF7DtmHigNFneShTfDob64QCsuunUzmy1tk/RiXAiBxM8N34voDhMRJfEhrtXbG7EfQ+HlAWjROllQpYyzh0QIhAKwXsh0zjJSOdq/lnrzODvTmagzVMMAfQGVXH8hPCYoQ
RSA明文: 我是你爸爸
RSA加密: nKkwvKO1nbeYLdjPSxLeQKy0bQ372/KKyDdiAOl18Nwnucd8OYL8VRbzzyccF5vf14RxKKOT74/rRz1vPimnbQ==
RSA解密: 我是你爸爸
-----------------------------
MD5明文: 我是你爸爸
MD5: 1d3ecc8cb56a34ee485fe33b3b54245e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值