16639036659
2023-12-11 e6ab9c2b7af85ac676ef9fbe616327eb20f04139
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
package com.ruoyi.doublePrevention.utilsCJ;
 
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
 
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
 
/**
* AES-GCM-256 工具类
* 加解密方法中已调用 Base64 方法
*/
public class AesGcm256Util {
 private static final SecureRandom SECURE_RANDOM = new
SecureRandom();
 public static final int NONCE_BIT_SIZE = 128;
 public static final int MAC_BIT_SIZE = 128;
 public static final int KEY_BIT_SIZE = 256;
 private AesGcm256Util() {
 }
 /**
 * 创建密钥
 *
 * @return 密钥
 */
 public static byte[] key() {
 byte[] key = new byte[KEY_BIT_SIZE / 8];
 SECURE_RANDOM.nextBytes(key);
 return key;
 }
 /**
 * 创建向量
 *
 * @return 向量
 */
//双重预防机制接口技术文档
 public static byte[] iv() {
 byte[] iv = new byte[NONCE_BIT_SIZE / 8];
 SECURE_RANDOM.nextBytes(iv);
 return iv;
 }
 /**
 * 编码
 *
 * @param hexStr 文本
 * @return 字节数组
 */
 public static byte[] hexToByte(String hexStr) {
 int len = hexStr.length();
 byte[] data = new byte[len / 2];
 for (int i = 0; i < len; i += 2) {
 data[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16) << 4)
 + Character.digit(hexStr.charAt(i + 1), 16));
 }
 return data;
 }
 /**
 * 转为十六进制
 *
 * @param data 字节数组
 * @return 转换结果
 */
 public static String toHex(byte[] data) {
 StringBuilder ret = new StringBuilder();
 for (byte datum : data) {
 String hex = Integer.toHexString(datum & 0xFF);
 if (hex.length() == 1) {
 hex = '0' + hex;
 }
 ret.append(hex.toUpperCase());
 }
 return ret.toString();
 }
 /**
 * 加密
 * @param plainText 明文文本
双重预防机制接口技术文档
 * @param key 密钥
 * @param iv 向量
 * @return 加密字符串
 */
 public static String encrypt(String plainText, byte[] key, byte[] iv) {
 String sr;
 try {
 byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8);
 GCMBlockCipher cipher = new GCMBlockCipher(new
         AESFastEngine());
 AEADParameters parameters =
 new AEADParameters(new KeyParameter(key),
MAC_BIT_SIZE, iv, null);
 cipher.init(true, parameters);
 byte[] encryptedBytes = new
byte[cipher.getOutputSize(plainBytes.length)];
 int retLen = cipher.processBytes(plainBytes, 0, plainBytes.length,
encryptedBytes, 0);
 cipher.doFinal(encryptedBytes, retLen);
 sr = Base64.getEncoder().encodeToString(encryptedBytes);
 } catch (Exception ex) {
 throw new RuntimeException(ex.getMessage());
 }
 return sr;
 }
 /**
 * 解密
 *
 * @param encryptedText 已加密文本
 * @param key 密钥
 * @param iv 向量
 * @return 已解密文本
 */
 public static String decrypt(String encryptedText, byte[] key, byte[] iv) {
 String sr;
 try {
 byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
 GCMBlockCipher cipher = new GCMBlockCipher(new
         AESFastEngine());
//双重预防机制接口技术文档
 AEADParameters parameters =
 new AEADParameters(new KeyParameter(key),
MAC_BIT_SIZE, iv, null);
 cipher.init(false, parameters);
 byte[] plainBytes = new
byte[cipher.getOutputSize(encryptedBytes.length)];
 int retLen = cipher.processBytes
 (encryptedBytes, 0, encryptedBytes.length, plainBytes, 0);
 cipher.doFinal(plainBytes, retLen);
 sr = new String(plainBytes, StandardCharsets.UTF_8);
 } catch (IllegalArgumentException | IllegalStateException |
         DataLengthException | InvalidCipherTextException ex) {
 throw new RuntimeException(ex.getMessage());
 }
 return sr;
 }
}