package cn.hmsoft.helper;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;

/**************************
 * 安全相关辅助类
 * 
 * @author zxq
 * @create 2018-04-07 21:30:25
 * @version 5.0.0
 * @email: revisit@126.com
 * @Company: www.hmsoft.cn
 */
public class SecureHelper {
	/**
	 * AES算法，保证JS加密能正常解密 //DES/ECB/NoPadding
	 */
	private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
	private final static String DESede = "DESede";

	/******************************
	 * MD5加密
	 */
	public static String md5(String input) {
		if (input == null)
			return null;
		byte[] digesta = null;
		try {
			MessageDigest alga = MessageDigest.getInstance("MD5");
			try {
				alga.update(input.getBytes("utf-8"));
			} catch (Exception e) {

			}
			digesta = alga.digest();
		} catch (NoSuchAlgorithmException e) {
			// e.printStackTrace();
		}
		return ByteHelper.bytesToHexString(digesta);
	}

	/******************************
	 * des加密
	 */

	public static String des3Encrypt(String source, byte[] password) {
		if (StringUtils.isEmpty(source))
			return "";
		byte[] b = des3Encrypt(source.getBytes(), password);
		if (b == null)
			return "";
		return ByteHelper.bytesToHexString(b);
	}

	/******************************
	 * des加密
	 */
	public static byte[] des3Encrypt(byte[] datasource, byte[] password) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(password, DESede);
			// 加密
			Cipher cipher = Cipher.getInstance(DESede);
			cipher.init(Cipher.ENCRYPT_MODE, deskey);
			return cipher.doFinal(datasource);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

	/***************************
	 * des解密加密
	 */
	public static String des3Decrypt(String source, byte[] password) {
		if (StringUtils.isEmpty(source))
			return "";
		byte[] b = des3Decrypt(ByteHelper.hexStringToBytes(source), password);
		if (b == null)
			return "";
		return new String(b);
	}

	/***************************
	 * des解密加密
	 */
	public static byte[] des3Decrypt(byte[] src, byte[] password) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(password, DESede);
			// 加密
			Cipher cipher = Cipher.getInstance(DESede);
			cipher.init(Cipher.DECRYPT_MODE, deskey);
			return cipher.doFinal(src);
		} catch (Exception e) {
			// e.printStackTrace();
			return null;
		}
	}

	public static byte[] getSecureKey(String key) {
		return getSecureKey(key, 24);
	}

	/************************************
	 * 根据字符串获得加解密数组
	 */
	public static byte[] getSecureKey(String key, int length) {
		return getSecureStringKey(key, length).getBytes();
	}

	public static String getSecureStringKey(String key, int length) {
		if (StringUtils.isEmpty(key))
			key = "00000000";
		if (key.length() > length)
			key = key.substring(0, length);
		else {
			int len = key.length();
			for (int i = 0; i < length - len; i++)
				key = "0" + key;
		}
		return key;
	}

	/**
	 * base 64 encode
	 */
	public static String base64Encode(byte[] bytes) {
		return Base64Utils.encodeToString(bytes);
	}

	/**
	 * base 64 decode
	 */
	public static byte[] base64Decode(String base64Code) {
		try {
			return StringUtils.isEmpty(base64Code) ? null : Base64Utils.decodeFromString(base64Code);
		} catch (Exception e) {
			return null;

		}
	}

	/**
	 * AES加密
	 */
	private static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {

		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128);
		Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
		byte[] key = getSecureKey(encryptKey, 16);
		cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"));

		return cipher.doFinal(content.getBytes("utf-8"));
	}

	/**
	 * AES加密为base 64 code
	 */
	public static String aesEncrypt(String content, String encryptKey) {
		try {
			return base64Encode(aesEncryptToBytes(content, encryptKey));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * AES解密
	 */
	private static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128);

		Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
		byte[] key = getSecureKey(decryptKey, 16);
		cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"));
		byte[] decryptBytes = cipher.doFinal(encryptBytes);

		return new String(decryptBytes);
	}

	/**
	 * 将base 64 code AES解密
	 */
	public static String aesDecrypt(String encryptStr, String decryptKey) {
		try {
			return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
		} catch (Exception e) {
			return null;
		}
	}
}
