/**
 * @Author: Kane Wang <wangkane@qq.com>
 * @Date: 2025-03-15 12:50:53
 * @LastEditors: Kane Wang
 * @LastModified: 2025-03-16 08:44:52
 * @FilePath: src/main/java/com/cpic/xim/utils/secrecy/AESUtils.java
 * @Description:
 * 
 *               Copyright (c) 2025 by Kane All rights reserved
 */
package com.cpic.xim.utils.secrecy;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * AESUtils
 */
public class AESUtils
{

    /**
     * 偏移量,必须是16位字符串
     */
    private static final String IV_STRING = "16-Bytes--String";

    /**
     * 产生随机密钥(这里产生密钥必须是16位)
     */
    private static String generateKey()
    {
        String key = UUID.randomUUID().toString();
        key = key.replace( "-", "" ).substring( 0, 16 );// 替换掉-号

        return key;
    }

    /**
     * 加密
     *
     * @param publicKey 公钥
     * @param content   加密数据
     * @return
     */
    public static Map<String, String> encryptData( String publicKey, String content )
    {
        byte[] encryptedBytes;
        try
        {
            byte[] byteContent = content.getBytes( "UTF-8" );
            // 注意，为了能与 iOS 统一
            // 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成
            String          key             = generateKey();
            byte[]          enCodeFormat    = key.getBytes();
            SecretKeySpec   secretKeySpec   = new SecretKeySpec( enCodeFormat, "AES" );
            byte[]          initParam       = IV_STRING.getBytes();
            IvParameterSpec ivParameterSpec = new IvParameterSpec( initParam );
            // 指定加密的算法、工作模式和填充方式
            Cipher cipher = Cipher.getInstance( "AES/CBC/PKCS5Padding" );
            cipher.init( Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec );
            encryptedBytes = cipher.doFinal( byteContent );
            // 同样对加密后数据进行 base64 编码
            key = RSAUtils.encryptByPublicKey( key, publicKey );
            Map<String, String> result = new HashMap<>( 2 );
            result.put( "key", key );
            result.put( "content", Base64Utils.encode( encryptedBytes ) );
            return result;
        }
        catch ( Exception e )
        {
            throw new RuntimeException( "加密失败：" + e.getMessage(), e );
        }
    }

    /**
     * 解密
     *
     * @param key
     * @param privateKey
     * @param content
     * @return
     */
    public static String decryptData( String key, String privateKey, String content )
    {
        try
        {
            System.out.println( "KEY:" + key );
            System.out.println( "privateKey:" + privateKey );
            System.out.println( "content:" + content );
            // base64 解码
            byte[] encryptedBytes = Base64Utils.decode( content );
            key = RSAUtils.decryptByPrivateKey( privateKey, key );
            byte[]          enCodeFormat    = key.getBytes();
            SecretKeySpec   secretKey       = new SecretKeySpec( enCodeFormat, "AES" );
            byte[]          initParam       = IV_STRING.getBytes();
            IvParameterSpec ivParameterSpec = new IvParameterSpec( initParam );
            Cipher          cipher          = Cipher.getInstance( "AES/CBC/PKCS5Padding" );
            cipher.init( Cipher.DECRYPT_MODE, secretKey, ivParameterSpec );
            byte[] result = cipher.doFinal( encryptedBytes );
            return new String( result, "UTF-8" );
        }
        catch ( Exception e )
        {
            throw new RuntimeException( "解密失败：" + e.getMessage(), e );
        }
    }

}
