package com.huawei.it.gts.ls.utils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Arrays;
/**
 * Created with IntelliJ IDEA.
 * User: rWX801871
 * Date: 2020/8/10 16:37
 * Description:
 */
public class AESEncryptUtilWithCBC {
    private static final Logger LOGGER = LoggerFactory.getLogger(AESEncryptUtilWithCBC.class);
    // 算法名称
    private static final String KEY_ALGORITHM = "AES";
    // 加解密算法/模式/填充方式
    private static final String ALGORITHM_STR = "AES/CBC/PKCS7Padding";
    private static final String DEFAULT_IV = "DUpSA4EPCLDlj0C2";
    private static Key key;
    private static Cipher cipher;
    private static byte[] iv = DEFAULT_IV.getBytes(StandardCharsets.UTF_8);
    public static void init(String sKey) {
        byte[] keyBytes = sKey.getBytes(StandardCharsets.UTF_8);
        // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        // 初始化
        Security.addProvider(new BouncyCastleProvider());
        // 转化成JAVA的密钥格式
        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
        try {
            // 初始化cipher
            cipher = Cipher.getInstance(ALGORITHM_STR, "BC");
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) {
            LOGGER.error("encrypt data fail:",e);
        }
    }
    /**
     * 加密方法
     *
     * @param content 要加密的字符串
     * @param sKey 加密密钥
     * @return
     */
    public static String encrypt(String content, String sKey) {
        byte[] encryptedText = null;
        init(sKey);
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
            encryptedText = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
            return Base64Utils.encodeToString(encryptedText);
        } catch (Exception e) {
            LOGGER.error("encrypt data fail:",e);
        }
        return"";
    }
    /**
     * 解密方法
     *
     * @param encryptedData 要解密的字符串
     * @param sKey 解密密钥
     * @return
     */
    public static String decrypt(String encryptedData, String sKey) {
        byte[] encryptedText = null;
        init(sKey);
        try {
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
            encryptedText = cipher.doFinal(Base64Utils.decodeFromString(encryptedData));
            return new String(encryptedText,StandardCharsets.UTF_8);
        } catch (Exception e) {
            LOGGER.error("decrypt data fail:",e);
        }
        return "";
    }
}