混合加密:标准AES-GCM + 自定义混淆
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class HybridEncryption {
private static final String BASE_ALGORITHM = "AES/GCM/NoPadding";
private static final int GCM_TAG_LENGTH = 128;
private static final int SALT_LENGTH = 16;
private static final int IV_LENGTH = 12;
// ==================== 核心加密方法 ====================
/**
* 混合加密:标准AES-GCM + 自定义混淆
*/
public static String hybridEncrypt(String plainText, String password) throws Exception {
// 第一阶段:标准加密保证安全性
byte[] standardCipher = performStandardEncryption(plainText, password);
// 第二阶段:自定义混淆增加隐蔽性
byte[] obfuscated = customObfuscation(standardCipher);
// 第三阶段:格式化为可传输的字符串
return formatOutput(obfuscated);
}
/**
* 混合解密
*/
public static String hybridDecrypt(String encryptedData, String password) throws Exception {
// 反向执行混淆层
byte[] obfuscated = parseInput(encryptedData);
byte[] standardCipher = reverseCustomObfuscation(obfuscated);
// 执行标准解密
return performStandardDecryption(standardCipher, password);
}
// ==================== 标准加密层 ====================
private static byte[] performStandardEncryption(String plainText, String password) throws Exception {
// 生成随机盐和IV
byte[] salt = generateRandomBytes(SALT_LENGTH);
byte[] iv = generateRandomBytes(IV_LENGTH);
// 从密码派生密钥
SecretKey secretKey = deriveKeyFromPassword(password, salt);
// 标准AES-GCM加密
Cipher cipher = Cipher.getInstance(BASE_ALGORITHM);
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec);
byte[] cipherText = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
// 组合:salt + iv + ciphertext
ByteBuffer buffer = ByteBuffer.allocate(salt.length + iv.length + cipherText.length);
buffer.put(salt);
buffer.put(iv);
buffer.put(cipherText);
return buffer.array();
}
private static String performStandardDecryption(byte[] encryptedData, String password) throws Exception {
ByteBuffer buffer = ByteBuffer.wrap(encryptedData);
byte[] salt = new byte[SALT_LENGTH];
byte[] iv = new byte[IV_LENGTH];
buffer.get(salt);
buffer.get(iv);
byte[] cipherText = new byte[buffer.remaining()];
buffer.get(cipherText);
// 派生密钥
SecretKey secretKey = deriveKeyFromPassword(password, salt);
// 解密
Cipher cipher = Cipher.getInstance(BASE_ALGORITHM);
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
byte[] plainText = cipher.doFinal(cipherText);
return new String(plainText, StandardCharsets.UTF_8);
}
// ==================== 自定义混淆层 ====================
/**
* 自定义混淆:可逆变换,不破坏安全性
*/
private static byte[] customObfuscation(byte[] data) {
if (data.length == 0) return data;
// 1. 字节重排(基于伪随机序列)
byte[] rearranged = rearrangeBytes(data);
// 2. 添加伪装头部(看起来像其他协议)
byte[] withHeader = addCamouflageHeader(rearranged);
// 3. 可逆的数值变换
byte[] transformed = applyValueTransformation(withHeader);
return transformed;
}
private static byte[] reverseCustomObfuscation(byte[] data) {
if (data.length == 0) return data;
// 反向执行混淆步骤
byte[] reversedTransform = reverseValueTransformation(data);
byte[] withoutHeader = removeCamouflageHeader(reversedTransform);
byte[] originalOrder = restoreByteOrder(withoutHeader);
return originalOrder;
}
// --- 具体的混淆技术 ---
private static byte[] rearrangeBytes(byte[] data) {
// 使用基于数据的伪随机重排
byte[] seed = Arrays.copyOf(data, Math.min(8, data.length));
Random random = new Random(Arrays.hashCode(seed));
byte[] result = Arrays.copyOf(data, data.length);
for (int i = 0; i < result.length; i++) {
int j = random.nextInt(result.length);
// 交换字节
byte temp = result[i];
result[i] = result[j];
result[j] = temp;
}
return result;
}
private static byte[] restoreByteOrder(byte[] data) {
// 由于重排是随机的,我们需要在混淆时记录顺序信息
// 这里简化处理:实际使用时需要更复杂的方案
return data; // 在实际方案中需要记录置换映射
}
private static byte[] addCamouflageHeader(byte[] data) {
// 添加看起来像HTTP或其他协议的头部
String fakeHeader = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
byte[] headerBytes = fakeHeader.getBytes(StandardCharsets.US_ASCII);
byte[] result = new byte[headerBytes.length + data.length];
System.arraycopy(headerBytes, 0, result, 0, headerBytes.length);
System.arraycopy(data, 0, result, headerBytes.length, data.length);
return result;
}
private static byte[] removeCamouflageHeader(byte[] data) {
// 查找并移除伪装头部
String fakeHeader = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
byte[] headerBytes = fakeHeader.getBytes(StandardCharsets.US_ASCII);
if (data.length < headerBytes.length) return data;
// 验证头部
for (int i = 0; i < headerBytes.length; i++) {
if (data[i] != headerBytes[i]) {
return data; // 不是我们的格式,直接返回
}
}
byte[] result = new byte[data.length - headerBytes.length];
System.arraycopy(data, headerBytes.length, result, 0, result.length);
return result;
}
private static byte[] applyValueTransformation(byte[] data) {
// 可逆的数值变换:加法模256
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++) {
result[i] = (byte) ((data[i] + 137) % 256 - 128); // 简单的仿射变换
}
return result;
}
private static byte[] reverseValueTransformation(byte[] data) {
// 逆变换
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++) {
result[i] = (byte) ((data[i] + 128 + 119) % 256); // 逆变换参数
}
return result;
}
// ==================== 辅助方法 ====================
private static SecretKey deriveKeyFromPassword(String password, byte[] salt) throws Exception {
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(), salt, 100000, 256);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] keyBytes = factory.generateSecret(spec).getEncoded();
return new SecretKeySpec(keyBytes, "AES");
}
private static byte[] generateRandomBytes(int length) {
byte[] bytes = new byte[length];
new SecureRandom().nextBytes(bytes);
return bytes;
}
private static String formatOutput(byte[] data) {
// 使用Base64编码,但可以添加自定义分隔符
String base64 = Base64.getEncoder().encodeToString(data);
return "ENC[" + base64.replace("=", "!") + "]";
}
private static byte[] parseInput(String input) {
if (!input.startsWith("ENC[") || !input.endsWith("]")) {
throw new IllegalArgumentException("Invalid format");
}
String base64 = input.substring(4, input.length() - 1).replace("!", "=");
return Base64.getDecoder().decode(base64);
}
}
支持 Ctrl+A 全选,Ctrl+C 复制