xieb
2023-08-07 236d6eea61ca295e9b50afac450780940d2a1799
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
package cn.gistack.system.user.sync.util;
 
 
import cn.gistack.system.user.sync.constant.CimsConstants;
import cn.gistack.system.user.sync.exception.BusinessException;
import cn.gistack.system.user.sync.exception.ErrorCode;
 
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
 
/**
 * AES加密解密
 * @author wd
 */
public class SecurityUtil {
 
    /**
     * AES加密
     *
     * @param content 明文
     * @return 密文
     */
    public static String encryptAES(String content, String secretKey) {
        checkParam(content,secretKey);
        //AES加密
        String encryptResultStr = encrypt(content, secretKey);
        //BASE64位加密
        encryptResultStr = ebotongEncrypto(encryptResultStr);
        return encryptResultStr;
    }
 
    /**
     * AES解密
     *
     * @param encryptResultStr 密文
     * @return 明文
     */
    public static String decryptAES(String encryptResultStr,String secretKey) {
        checkParam(encryptResultStr,secretKey);
        try {
            // BASE64位解密
            String decrpt = ebotongDecrypto(encryptResultStr);
            byte[] decryptFrom = hexToByteArray(decrpt);
            //AES解密
            byte[] decryptResult = decrypt(decryptFrom, secretKey);
            return new String(decryptResult);
        } catch (Exception e) {
            e.printStackTrace();
            // 当密文不规范时会报错,可忽略,但调用的地方需要考虑
            throw new BusinessException(ErrorCode.CONTENT_EMPTY_ERROR);
        }
    }
 
    /**
     * 校验参数
     */
    private static void checkParam(String encryptResultStr,String secretKey){
        if (isBlank(encryptResultStr)) {
            throw new BusinessException(ErrorCode.CONTENT_EMPTY_ERROR);
        }
        if (secretKey.length() != CimsConstants.SECRET_KEY_LENGTH || !secretKey.matches(CimsConstants.SECRET_KEY_REGEX)) {
            throw new BusinessException(ErrorCode.SECRET_KEY_ERROR);
        }
    }
 
 
    /**
     * 加密
     *
     * @param content  需要加密的内容
     * @param password 加密密码
     * @return
     */
    private static String encrypt(String content, String password) {
        try {
            byte[] raw = password.getBytes(CimsConstants.SECRET_KEY_ENCODING);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] byteRresult = cipher.doFinal(content.getBytes(CimsConstants.SECRET_KEY_ENCODING));
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < byteRresult.length; i++) {
                String hex = Integer.toHexString(byteRresult[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.CONTENT_ENCODE_ERROR);
        }
    }
 
    /**
     * 解密
     *
     * @param content  待解密内容
     * @param password 解密密钥
     * @return
     */
    private static byte[] decrypt(byte[] content, String password) {
        try {
            byte[] raw = password.getBytes(CimsConstants.SECRET_KEY_ENCODING);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(ErrorCode.SECRET_DECODE_ERROR);
        }
    }
 
    /**
     * hex字符串转byte数组
     * @param inHex 待转换的Hex字符串
     * @return  转换后的byte数组结果
     */
    private static byte[] hexToByteArray(String inHex){
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1){
            //奇数
            hexlen++;
            result = new byte[(hexlen/2)];
            inHex="0"+inHex;
        }else {
            //偶数
            result = new byte[(hexlen/2)];
        }
        int j=0;
        for (int i = 0; i < hexlen; i+=2){
            result[j] = hexToByte(inHex.substring(i,i+2));
            j++;
        }
        return result;
    }
 
    /**
     * Hex字符串转byte
     * @param inHex 待转换的Hex字符串
     * @return  转换后的byte
     */
    private static byte hexToByte(String inHex){
        return (byte)Integer.parseInt(inHex,16);
    }
 
    /**
     * Base64加密字符串
     */
    private static String ebotongEncrypto(String str) {
        String result = str;
        if (str != null && str.length() > 0) {
            try {
                byte[] encodeByte = str.getBytes(CimsConstants.SECRET_KEY_ENCODING);
                result = Base64.getEncoder().encodeToString(encodeByte);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // base64加密超过一定长度会自动换行 需要去除换行符
        return result.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");
    }
 
    /**
     * Base64解密字符串
     */
    private static String ebotongDecrypto(String str) {
        byte[] encodeByte = Base64.getDecoder().decode(str);
        return new String(encodeByte);
    }
 
    /**
     * 判断字符串是否为空
     * @param cs
     * @return
     */
    private static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }
 
}