package com.qmth.teachcloud.common.util;

import com.qmth.teachcloud.common.contant.SystemConstant;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;

/**
 * @Description: AES对称加密
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2019/10/11
 */
public class AesUtil {
    private final static Logger log = LoggerFactory.getLogger(AesUtil.class);

    /**
     * 加密
     *
     * @param content
     * @param strKey
     * @return
     * @throws Exception
     */
    private static byte[] encrypt(String content, String strKey) throws Exception {
        SecretKeySpec skeySpec = getKey(strKey);
        Cipher cipher = Cipher.getInstance(SystemConstant.AES_MODE_PKCS5);
        IvParameterSpec iv = new IvParameterSpec(SystemConstant.AES_RULE.getBytes());//AES规则，可自定义，例如A-Z排序
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        return cipher.doFinal(content.getBytes());
    }

    /**
     * 解密
     *
     * @param content
     * @param strKey
     * @return
     * @throws Exception
     */
    private static String decrypt(byte[] content, String strKey) throws Exception {
        SecretKeySpec skeySpec = getKey(strKey);
        Cipher cipher = Cipher.getInstance(SystemConstant.AES_MODE_PKCS5);
        IvParameterSpec iv = new IvParameterSpec(SystemConstant.AES_RULE.getBytes());//AES规则，可自定义，例如A-Z排序
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] original = cipher.doFinal(content);
        return new String(original);
    }

    /**
     * 公钥
     *
     * @param strKey
     * @return
     * @throws Exception
     */
    private static SecretKeySpec getKey(String strKey) throws Exception {
        byte[] arrBTmp = strKey.getBytes();
        byte[] arrB = new byte[16]; // 创建一个空的16位字节数组（默认值为0）
        for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
            arrB[i] = arrBTmp[i];
        }
        return new SecretKeySpec(arrB, SystemConstant.AES);
    }

    /**
     * AES加密
     *
     * @param content
     * @param encryptKey
     * @return
     * @throws Exception
     */
    public static String encoder(String content, String encryptKey) throws Exception {
        String encoderText = Base64.getEncoder().encodeToString(encrypt(content, encryptKey));
        return encoderText;
    }

    /**
     * AES解密
     *
     * @param encryptStr
     * @param decryptKey
     * @return
     * @throws Exception
     */
    public static String decoder(String encryptStr, String decryptKey) throws Exception {
        String decoderText = decrypt(Base64.getDecoder().decode(encryptStr), decryptKey);
        return decoderText;
    }

    /**
     * cs7加密/解密用
     */
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * cs7加密
     *
     * @param content
     * @param key
     * @return
     */
    public static String encryptCs7(String content, String key) {
        String encoderText = null;
        try {
            Cipher cipher = Cipher.getInstance(SystemConstant.AES_MODE_PKCS7);
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(SystemConstant.CHARSET_NAME), SystemConstant.AES);
            AlgorithmParameterSpec paramSpec = new IvParameterSpec(SystemConstant.AES_RULE.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, paramSpec);
            byte[] result = cipher.doFinal(content.getBytes(SystemConstant.CHARSET_NAME));
            encoderText = Base64.getEncoder().encodeToString(result);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
        }
        return encoderText;
    }

    /**
     * cs7解密
     *
     * @param content
     * @param key
     * @return
     */
    public static String decryptCs7(String content, String key) {
        String decoderText = null;
        try {
            Cipher cipher = Cipher.getInstance(SystemConstant.AES_MODE_PKCS7);
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(SystemConstant.CHARSET_NAME), SystemConstant.AES);
            AlgorithmParameterSpec paramSpec = new IvParameterSpec(SystemConstant.AES_RULE.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, keySpec, paramSpec);
            decoderText = new String(cipher.doFinal(Base64.getDecoder().decode(content)), SystemConstant.CHARSET_NAME);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
        }
        return decoderText;
    }
}
