package com.unionpay.acp.sdk;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Arrays;


public class AesUtils {

    // private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/NoPadding";//默认的加密算法
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";//默认的加密算法
    /**
     * AES 加密操作
     * @param content 待加密内容
     * @param password 加密密钥
     * @return 返回Base64转码后的加密数据
     */
    public static String encrypt(String content, String password) {
        try {
            SecretKeySpec skeySpec = getKey(password);
            byte[] clearText = content.getBytes(StandardCharsets.UTF_8);
            final byte[] iv = new byte[16];
            Arrays.fill(iv, (byte) 0x00);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);

            return Base64.encodeBase64String(cipher.doFinal(clearText));
        } catch (Exception ignored) {
        }
        return null;
    }

    /**
     * AES 解密操作
     *
     * @param content 待解密内容
     * @param password 解密密钥
     * @return 返回解密后数据
     */
    public static String decrypt(String content, String password) {
        try {
            SecretKey key = getKey(password);
            final byte[] iv = new byte[16];
            Arrays.fill(iv, (byte) 0x00);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

            byte[] encryptedPwdBytes = Base64.decodeBase64(content);
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
            byte[] decryptedValueBytes = (cipher.doFinal(encryptedPwdBytes));

            return new String(decryptedValueBytes , StandardCharsets.UTF_8);
        } catch (Exception ex) {
            System.err.println("Decrypt exception: " + ex.getMessage());
        }
        return null;
    }

    private static SecretKeySpec getKey(String password) throws UnsupportedEncodingException {
        int keyLength = 256;
        byte[] keyBytes = new byte[keyLength / 8];
        Arrays.fill(keyBytes, (byte) 0x0);
        byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8);
        int length = Math.min(passwordBytes.length, keyBytes.length);
        System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
        return new SecretKeySpec(keyBytes, "AES");
    }
}