package com.bonus.common.core.utils.encryption;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

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

/**
 *
 * AES加密工具类
 */
@Slf4j
@Component
public class AESCBCUtil {

	//使用AES-256-CBC加密模式，key需要为16位,key和iv可以相同！
		/**
		 * 密钥算法
		 */
		private static final String KEY_ALGORITHM = "AES";

		/**
		 * 加密/解密算法 / 工作模式 / 填充方式
		 * Java 6支持PKCS5Padding填充方式
		 * Bouncy Castle支持PKCS7Padding填充方式
		 */
		private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";

		/**
		 * 偏移量，只有CBC模式才需要
		 */
		private final static String ivParameter = "1234567812345678";

		/**
		 * AES要求密钥长度为128位或192位或256位，java默认限制AES密钥长度最多128位
		 */
//		public static String sKey = "zhst@bonus@zhst@bonus@1234567890";
		public static String sKey = "zhst@bonus@zhst@";

		/**
		 * 编码格式
		 */
		public static final String ENCODING = "utf-8";

		static {
			//如果是PKCS7Padding填充方式，则必须加上下面这行
			Security.addProvider(new BouncyCastleProvider());
		}

		/**
		 * AES加密
		 *（CBC模式）
		 * @param source 源字符串
		 * @param
		 * @throws Exception
		 * @return 加密后的密文
		 */
		public static String encrypt(String source) throws Exception {
			String	key=sKey;
			byte[] sourceBytes = source.getBytes(ENCODING);
			byte[] keyBytes = key.getBytes(ENCODING);
			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
			IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes(ENCODING));
			cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, KEY_ALGORITHM), iv);
			byte[] decrypted = cipher.doFinal(sourceBytes);
			return Base64.encodeBase64String(decrypted);
		}

		/**
		 * AES解密
		 *（CBC模式）
		 * @param encryptStr 加密后的密文
		 * @param
		 * @throws Exception
		 * @return 源字符串
		 */
		public static String decrypt(String encryptStr)  {
			try{
				String key=sKey;
				byte[] sourceBytes = Base64.decodeBase64(encryptStr);
				byte[] keyBytes = key.getBytes(ENCODING);

				int base = 16;
				if (keyBytes.length % base != 0) {
					int groups = keyBytes.length / base + 1;
					byte[] temp = new byte[groups * base];
					Arrays.fill(temp, (byte) 0);
					System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
					keyBytes = temp;
				}
				Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
				IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes(ENCODING));
				cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, KEY_ALGORITHM), iv);
				byte[] decoded = cipher.doFinal(sourceBytes);
				return new String(decoded, ENCODING);
			}catch (Exception e){
				log.error(e.toString(),e);
			}
			return  "";
		}


		public static void main(String[] args) throws Exception {
			String jmData= AESCBCUtil.encrypt("15240004260wechat");
			String jmData1= AESCBCUtil.encrypt("GZkq@123456!");
			System.out.println("加密后字符串：" + jmData);
			System.out.println("加密后字符串：" + jmData1);
			String data= AESCBCUtil.decrypt(jmData);
			System.out.println("解密后的字串是：" + data);

			/*String key = "1234567812345678";
			// 加密
			long lStart = System.currentTimeMillis();
			String enString = AESCBCUtils.encrypt("2023-06-06", AESCBCUtils.sKey);
			System.out.println("加密后的字串是：" + enString);
			 enString = AESCBCUtils.encrypt("Bonus@admin123", AESCBCUtils.sKey);
			System.out.println("加密后的字串是：" + enString);
			long lUseTime = System.currentTimeMillis() - lStart;
			System.out.println("加密耗时：" + lUseTime + "毫秒");

			// 解密
			lStart = System.currentTimeMillis();
			String DeString = AESCBCUtils.decrypt("[encoded data, 5356 characters]");
			System.out.println("解密后的字串是：" + DeString);
			lUseTime = System.currentTimeMillis() - lStart;
			System.out.println("解密耗时：" + lUseTime + "毫秒");*/
//			String key = "1234567812345678";
//			// 加密
//			long lStart = System.currentTimeMillis();
//			String enString = AESCBCUtils.encrypt("admin@123", AESCBCUtils.sKey);
//			String enString2 = AESCBCUtils.encrypt("cwchen", AESCBCUtils.sKey);
//			String enString3 = AESCBCUtils.encrypt("1", AESCBCUtils.sKey);
//			String enString4= AESCBCUtils.encrypt("10", AESCBCUtils.sKey);
//           String name="";
//			for (int i = 0; i <70 ; i++) {
//				name="admin"+i;
//				String pwd= AESCBCUtils.encrypt(name,AESCBCUtils.sKey);
//				System.out.println("用户名:"+name+"      "+"加密后密码:"+pwd);
//			}
		}



}
