package com.cool.store.utils;

import com.cool.store.exception.ServiceException;
import org.springframework.util.Assert;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters;
import java.util.Arrays;
import java.util.Base64;

/**
 * @author zhangchenbiao
 * @FileName: AesUtil
 * @Description:
 * @date 2023-05-29 14:28
 */

public class AesUtil {

    private static final Charset utf8 = StandardCharsets.UTF_8;


    public static String genAesKey() {
        return StringUtil.random(32);
    }

    public static String encrypt(String content, String aesTextKey) {
        return Base64.getEncoder().encodeToString(encrypt(content.getBytes(utf8), aesTextKey.getBytes(utf8)));
    }

    public static String decrypt(String content, String aesTextKey) {
        byte[] buffer = Base64.getDecoder().decode(content);
        return new String(decrypt(buffer, aesTextKey.getBytes(utf8)), utf8);
    }

    public static byte[] encrypt(byte[] content, byte[] aesKey) {
        Assert.isTrue(aesKey.length == 32, "IllegalAesKey, aesKey's length must be 32");
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            return cipher.doFinal(Pkcs7Encoder.encode(content));
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    public static byte[] decrypt(byte[] encrypted, byte[] aesKey) {
        Assert.isTrue(aesKey.length == 32, "IllegalAesKey, aesKey's length must be 32");
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            return Pkcs7Encoder.decode(cipher.doFinal(encrypted));
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    public static String decryptWechat(String sessionKey, String encryptedData, String ivStr) {
        try {
            AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
            params.init(new IvParameterSpec(Base64.getDecoder().decode(ivStr)));
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(2, new SecretKeySpec(Base64.getDecoder().decode(sessionKey), "AES"), params);
            return new String(Pkcs7Encoder.decode(cipher.doFinal(Base64.getDecoder().decode(encryptedData))), StandardCharsets.UTF_8);
        } catch (Exception var5) {
            throw new ServiceException("AES解密失败");
        }
    }
}
