标准AES-GCM+自定义混淆工具类

2026年01月23日 08:06

描述

混合加密:标准AES-GCM + 自定义混淆

标签

Java
标准AES_GCM自定义混淆工具类.txt 8,017 字符 | 232 行
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 复制