jiangping
2025-07-16 c2d3591648b215ab29fc14cab1c747ba58798412
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
package com.doumee.core.utils;
 
import java.nio.charset.StandardCharsets;
import java.security.Security;
 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
 
/**
 * AES加解密
 * @author  dm
 * @since 2025/03/31 16:44
 */
@Data
@Component
public class AES {
 
    // 密钥
    @Value("${security.aes.key}")
    private String key;
 
    // 偏移量
    @Value("${security.aes.iv}")
    private String iv;
 
    // 密钥长度
    private Integer keyLen = 128;
 
    public AES() {
        Security.addProvider(new BouncyCastleProvider());
    }
 
    /**
     * 加密
     *
     * @return String
     */
    public String encrypt(String plainText) throws SecurityException {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");// 创建密码器
            cipher.init(Cipher.ENCRYPT_MODE, this.getAESKey(), new IvParameterSpec(paddingIv(iv)));// 初始化
            return new Base64().encodeAsString(cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)));
        } catch (Exception e) {
            throw new SecurityException("AES encrypt throw an exception", e);
        }
    }
 
    /**
     * 解密
     *
     * @param cipherText 密文
     * @return String
     */
    public String decrypt(String cipherText) throws SecurityException {
        try {
            byte[] encrypted = new Base64().decode(cipherText);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            cipher.init(Cipher.DECRYPT_MODE, this.getAESKey(), new IvParameterSpec(paddingIv(iv)));
            return new String(cipher.doFinal(encrypted), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new SecurityException("AES decrypt throw an exception", e);
        }
    }
 
    /**
     * 获取AES key
     *
     * @return SecretKeySpec
     */
    private SecretKeySpec getAESKey() {
        /* 使用原始密钥进行加密,要求密钥为密钥长度的倍数 */
        byte[] raw = key.getBytes(StandardCharsets.UTF_8);
        return new SecretKeySpec(raw, "AES");
    }
 
    /**
     * 初始化向量一直保持16位
     *
     * @param iv 向量
     * @return byte[]
     */
    private byte[] paddingIv(String iv) {
        byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8);
        byte[] bs = new byte[keyLen / 8];
        System.arraycopy(ivBytes, 0, bs, 0, ivBytes.length);
        return bs;
    }
}