liusheng
2 天以前 4c0da4f99ca97d2cfcaa00fd5cd9c3d69d089bfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.ruoyi.common.utils;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
 
/**
 * AES 加解密工具类
 * 算法:AES/CBC/PKCS5Padding(等效 PKCS7,128 位数据块)
 * 输出:HEX 大写字符串
 * 字符集:UTF-8
 */
public class AesUtils {
 
    /** 算法/模式/填充 */
    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
 
    /** 默认 Key(HEX,32字节→256位密钥) */
    private static final String DEFAULT_KEY = "0F471C56362408AF8DB929C38EDFD23C";
 
    /** 默认 IV(HEX,16字节→128位偏移量) */
    private static final String DEFAULT_IV = "11BEE6E35B881A33CF1649607295D1A7";
 
    private AesUtils() {
    }
 
    // -------------------------------------------------------------------------
    // 公共 API
    // -------------------------------------------------------------------------
 
    /**
     * 使用默认 Key / IV 加密
     *
     * @param plainText 明文
     * @return HEX 大写密文
     */
    public static String encrypt(String plainText) {
        return encrypt(plainText, DEFAULT_KEY, DEFAULT_IV);
    }
 
    /**
     * 使用默认 Key / IV 解密
     *
     * @param hexCipherText HEX 大写密文
     * @return 明文
     */
    public static String decrypt(String hexCipherText) {
        return decrypt(hexCipherText, DEFAULT_KEY, DEFAULT_IV);
    }
 
    /**
     * AES-CBC 加密
     *
     * @param plainText  明文
     * @param hexKey     HEX 格式的密钥(16/24/32字节对应128/192/256位)
     * @param hexIv      HEX 格式的偏移量(16字节)
     * @return HEX 大写密文
     */
    public static String encrypt(String plainText, String hexKey, String hexIv) {
        try {
            byte[] keyBytes = hexToBytes(hexKey);
            byte[] ivBytes = hexToBytes(hexIv);
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
            byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(encrypted).toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException("AES 加密失败", e);
        }
    }
 
    /**
     * AES-CBC 解密
     *
     * @param hexCipherText HEX 大写密文
     * @param hexKey        HEX 格式的密钥
     * @param hexIv         HEX 格式的偏移量
     * @return 明文
     */
    public static String decrypt(String hexCipherText, String hexKey, String hexIv) {
        try {
            byte[] keyBytes = hexToBytes(hexKey);
            byte[] ivBytes = hexToBytes(hexIv);
            byte[] cipherBytes = hexToBytes(hexCipherText);
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
            byte[] decrypted = cipher.doFinal(cipherBytes);
            return new String(decrypted, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("AES 解密失败", e);
        }
    }
 
    // -------------------------------------------------------------------------
    // 私有辅助方法
    // -------------------------------------------------------------------------
 
    /**
     * HEX 字符串转字节数组(大小写均可)
     */
    private static byte[] hexToBytes(String hex) {
        if (hex == null || hex.length() % 2 != 0) {
            throw new IllegalArgumentException("非法 HEX 字符串:" + hex);
        }
        int len = hex.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return data;
    }
 
    /**
     * 字节数组转 HEX 字符串(小写,调用方统一转大写)
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}