package com.gk.hotwork.doublePrevention.utils;
|
|
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;
|
}
|
}
|