package com.sqx.modules.utils;

import lombok.val;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;

public class AESCBCWithRandomIV {

    private static final String AES = "AES";
    private static final String AES_CBC_PADDING = "AES/CBC/PKCS5Padding";
    private static final int IV_SIZE = 16; // 16 bytes for AES block size
    private static final int KEY_SIZE = 128;

    // ⚠️ 真实项目中，请从安全的配置中读取密钥，避免硬编码！
    private static final String SECRET_KEY = "nihyMG%DJ0I0nhlA"; // 16 bytes = 128 bits

    /**
     * AES CBC 加密，随机生成 IV 并一起编码返回（IV + CipherText）
     */
    public static String encrypt(String plainText,String secretKey) throws Exception {
        byte[] keyBytes = secretKey.getBytes("UTF-8");
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, AES);

        // 随机 IV
        byte[] ivBytes = new byte[IV_SIZE];
        new SecureRandom().nextBytes(ivBytes);
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        Cipher cipher = Cipher.getInstance(AES_CBC_PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));

        // 拼接 IV + 加密内容
        byte[] combined = new byte[IV_SIZE + encryptedBytes.length];
        System.arraycopy(ivBytes, 0, combined, 0, IV_SIZE);
        System.arraycopy(encryptedBytes, 0, combined, IV_SIZE, encryptedBytes.length);

        return Base64.getEncoder().encodeToString(combined);
    }

    /**
     * AES CBC 解密，从密文中提取 IV 解密
     */
    public static String decrypt(String base64CipherText,String secretKey) throws Exception {
        byte[] combined = Base64.getDecoder().decode(base64CipherText);

        byte[] ivBytes = new byte[IV_SIZE];
        byte[] encryptedBytes = new byte[combined.length - IV_SIZE];

        System.arraycopy(combined, 0, ivBytes, 0, IV_SIZE);
        System.arraycopy(combined, IV_SIZE, encryptedBytes, 0, encryptedBytes.length);

        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), AES);

        Cipher cipher = Cipher.getInstance(AES_CBC_PADDING);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decrypted = cipher.doFinal(encryptedBytes);

        return new String(decrypted, "UTF-8");
    }

    public static String getSecretKey(){
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-=.$%^&*#";
        SecureRandom random = new SecureRandom();
        StringBuilder key = new StringBuilder(16);

        for (int i = 0; i < 16; i++) {
            key.append(chars.charAt(random.nextInt(chars.length())));
        }
        System.out.println("随机生成的密钥: " + key.toString());
        return key.toString();
    }

    // 🔍 示例测试
    public static void main(String[] args) throws Exception {
        String text = "210421200001084233";
        val key = getSecretKey();
        String encrypted = encrypt(text,key);
        String decrypted = decrypt(encrypted,key);


        System.out.println("原文: " + text);
        System.out.println("加密: " + encrypted);
        System.out.println("解密: " + decrypted);
    }
}


