package cn.security.jasypt;

import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.jasypt.properties.PropertyValueEncryptionUtils;
import org.jasypt.util.text.BasicTextEncryptor;


public class JasyptUtil 
{
	private static final String PBEWITHMD5ANDDES = "PBEWithMD5AndDES";
	private static final String PBEWITHHMACSHA512ANDAES_256 = "PBEWITHHMACSHA512ANDAES_256";

	/**
	 * @Description: Jasyp加密（PBEWithMD5AndDES）
	 * @param		 plainText      待加密的原文
	 * @param		 factor         加密秘钥
	 */
	public static String encryptWithMD5(String plainText, String factor) {
		// 1. 创建加解密工具实例
		StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
		// 2. 加解密配置
		EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
		config.setAlgorithm(PBEWITHMD5ANDDES);
		config.setPassword(factor);
		encryptor.setConfig(config);
		// 3. 加密
		return encryptor.encrypt(plainText);
	}

	/**
	 * @Description: Jaspy解密（PBEWithMD5AndDES）
	 * @param		 encryptedText      待解密密文
	 * @param		 factor             解密秘钥
	 */
	public static String decryptWithMD5(String encryptedText, String factor) {
		// 1. 创建加解密工具实例
		StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
		// 2. 加解密配置
		EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
		config.setAlgorithm(PBEWITHMD5ANDDES);
		config.setPassword(factor);
		encryptor.setConfig(config);
		// 3. 解密
		return encryptor.decrypt(encryptedText);
	}

	/**
	 * @Description: Jasyp 加密（PBEWITHHMACSHA512ANDAES_256）
	 * @param		 plainText  待加密的原文
	 * @param		 factor     加密秘钥
	 */
	public static String encryptWithSHA512(String plainText, String factor) {
		// 1. 创建加解密工具实例
		PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
		// 2. 加解密配置
		SimpleStringPBEConfig config = getSimpleStringPBEConfig(PBEWITHHMACSHA512ANDAES_256,factor);
		encryptor.setConfig(config);
		// 3. 加密
		return encryptor.encrypt(plainText);
	}

	/**
	 * @Description: Jaspy解密（PBEWITHHMACSHA512ANDAES_256）
	 * @param		 encryptedText  待解密密文
	 * @param		 factor         解密秘钥
	 */
	public static String decryptWithSHA512(String encryptedText, String factor) {
		// 1. 创建加解密工具实例
		PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
		// 2. 加解密配置
		SimpleStringPBEConfig config = getSimpleStringPBEConfig(PBEWITHHMACSHA512ANDAES_256,factor);
		encryptor.setConfig(config);
		// 3. 解密
		return encryptor.decrypt(encryptedText);
	}    

	/**
	 * 设置 {@link PBEConfig} 配置对象，SimpleStringPBEConfig 是它的实现类
	 * 1、所有的配置项建议与全局配置文件中的配置项保持一致，特别是 password、algorithm 等等选项，如果不一致，则应用启动时解密失败而报错.
	 * 2、setPassword(final String password)：设置加密密钥，必须与全局配置文件中配置的保存一致，否则应用启动时会解密失败而报错.
	 * 3、setPoolSize(final String poolSize)：设置要创建的加密程序池的大小.
	 * 4、setAlgorithm(final String algorithm): 设置加密算法的值， 此算法必须由 JCE 提供程序支持
	 * 5、setKeyObtentionIterations: 设置应用于获取加密密钥的哈希迭代次数。
	 * 6、setProviderName(final String providerName)：设置要请求加密算法的安全提供程序的名称
	 * 7、setSaltGeneratorClassName：设置 Sal 发生器
	 * 8、setIvGeneratorClassName：设置 IV 发生器
	 * 9、setStringOutputType：设置字符串输出的编码形式。可用的编码类型有 base64、hexadecimal
	 *
	 * @param secretKey
	 * @return
	 */
	private static SimpleStringPBEConfig getSimpleStringPBEConfig(String algName,String secretKey) {
		SimpleStringPBEConfig config = new SimpleStringPBEConfig();
		config.setPassword(secretKey);
		config.setAlgorithm(algName);
		config.setKeyObtentionIterations("1000");
		config.setPoolSize("1");
		config.setProviderName("SunJCE");
		config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
		config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
		config.setStringOutputType("base64");
		return config;
	}
	
	
	private static BasicTextEncryptor basicTextEncryptor = new BasicTextEncryptor();
	static {
		basicTextEncryptor.setPassword("lybgeek");//默认盐
	}
	/**
	 * Jasypt加解密专用一：12345678:iqA9Fm5QP3K/uweJwvuHRy+kF4SyO9LZ
	 * 解密的工具类是BasicTextEncryptor，其对应配置加解密就是PBEWithMD5AndDES
	 * 和org.jasypt.iv.NoIvGenerator
	 */ 	
	/**明文加密 */
	public static String encode(String plaintext){
		String ciphertext = basicTextEncryptor.encrypt(plaintext);
		return ciphertext;
	}
	/** 解密*/
	public static String decode(String ciphertext){
		ciphertext = "ENC(" + ciphertext + ")";
		if (PropertyValueEncryptionUtils.isEncryptedValue(ciphertext)){
			String plaintext = PropertyValueEncryptionUtils.decrypt(ciphertext,basicTextEncryptor);
			return plaintext;
		}
		return "";
	}
	
	public static void main(String[] args) {
		/*
		
		System.out.println("采用密343文：" + decode(encode("12345678")));
		
		String factor = "xxxx@2020";
		String plainText = "123456";
		String encryptWithMD5Str = encryptWithMD5(plainText, factor);
		String decryptWithMD5Str = decryptWithMD5(encryptWithMD5Str, factor);

		String encryptWithSHA512Str = encryptWithSHA512(plainText, factor);
		String decryptWithSHA512Str = decryptWithSHA512(encryptWithSHA512Str, factor);
		System.out.println("采用MD5加密前原文密文：" + encryptWithMD5Str);
		System.out.println("采用MD5解密后密文原文:" + decryptWithMD5Str);
		System.out.println();
		System.out.println("采用SHA512加密前原文密文：" + encryptWithSHA512Str);
		System.out.println("采用SHA512长度：" + encryptWithSHA512Str.length());
		System.out.println("采用SHA512解密后密文原文:" + decryptWithSHA512Str);
*/
	}
}