
package com.sys.util;

import com.antherd.smcrypto.sm2.Keypair;
import com.antherd.smcrypto.sm2.Sm2;
import com.antherd.smcrypto.sm3.Sm3;
import com.antherd.smcrypto.sm4.Sm4;
import com.antherd.smcrypto.sm4.Sm4Options;

/**
 * 加密工具类，本框架目前使用 https://github.com/antherd/sm-crypto 项目中一些加解密方式
 * 使用小伙伴需要过等保密评相关，请在此处更改为自己的加密方法，或加密机，使用加密机同时需要替换公钥，私钥在内部无法导出，提供加密的方法
 * 如果不涉及到加密机方面的内容，请更改公私要为自己重新生成的，生成方式请看集成的sm-crypto主页
 *
 * 
 * @date 2022/9/15 21:51
 */
public class SmCryptoUtil {

	/** 公钥 */
	private static final String PUBLIC_KEY = "04f7c7959e0c2b88a871de09d6c04e791faf07a8b0dea45452a15a0d0499ca0e0d89b52c1e310b6b29ccb6fdd8491ce7c6c90f36e265a5426dd0c86c95a56e97f9";

	/** 私钥 */
	private static final String PRIVATE_KEY = "a71a590a4befd50ce0e6ec2b106b0b39f7216b26f872cfe99f7d834d9b856745";

	/** SM4的对称秘钥（生产环境需要改成自己使用的） 16 进制字符串，要求为 128 比特 */
	private static final String KEY = "0123456789abcdeffedcba9876543210";

	/**
	 * 加密方法（Sm2 的专门针对前后端分离，非对称秘钥对的方式，暴露出去的公钥，对传输过程中的密码加个密）
	 *
	 * 
	 * @date 2022/9/15 21:51
	 * @param str 待加密数据
	 * @return 加密后的密文
	 */
	public static String doSm2Encrypt(String str) {
		return Sm2.doEncrypt(str, PUBLIC_KEY);
	}

	/**
	 * 解密方法 如果采用加密机的方法，用try catch 捕捉异常，返回原文值即可
	 *
	 * 
	 * @date 2022/9/15 21:51
	 * @param str 密文
	 * @return 解密后的明文
	 */
	public static String doSm2Decrypt(String str) {
		// 解密
		return Sm2.doDecrypt(str, PRIVATE_KEY);
	}

	/**
	 * 加密方法
	 *
	 * 
	 * @date 2022/9/15 21:51
	 * @param str 待加密数据
	 * @return 加密后的密文
	 */
	public static String doSm4CbcEncrypt(String str) {
		// SM4 加密 cbc模式
		Sm4Options sm4Options4 = new Sm4Options();
		sm4Options4.setMode("cbc");
		sm4Options4.setIv("fedcba98765432100123456789abcdef");
		return Sm4.encrypt(str, KEY, sm4Options4);
	}

	/**
	 * 解密方法 如果采用加密机的方法，用try catch 捕捉异常，返回原文值即可
	 *
	 * 
	 * @date 2022/9/15 21:51
	 * @param str 密文
	 * @return 解密后的明文
	 */
	public static String doSm4CbcDecrypt(String str) {
		// 解密，cbc 模式，输出 utf8 字符串
		Sm4Options sm4Options8 = new Sm4Options();
		sm4Options8.setMode("cbc");
		sm4Options8.setIv("fedcba98765432100123456789abcdef");
		String docString = Sm4.decrypt(str, KEY, sm4Options8);
		if (docString.equals("")) {
			return str;
		} else {
			return docString;
		}
	}

	/**
	 * 纯签名
	 *
	 * 
	 * @date 2022/9/15 21:51
	 * @param str 待签名数据
	 * @return 签名结果
	 */
	public static String doSignature(String str) {
		return Sm2.doSignature(str, PRIVATE_KEY);
	}

	/**
	 * 验证签名结果
	 *
	 * 
	 * @date 2022/9/15 21:51
	 * @param originalStr 签名原文数据
	 * @param str         签名结果
	 * @return 是否通过
	 */
	public static boolean doVerifySignature(String originalStr, String str) {
		return Sm2.doVerifySignature(originalStr, str, PUBLIC_KEY);
	}

	/**
	 * 通过杂凑算法取得hash值，用于做数据完整性保护
	 *
	 * 
	 * @date 2022/9/15 21:51
	 * @param str 字符串
	 * @return hash 值
	 */
	public static String doHashValue(String str) {
		return Sm3.sm3(str);
	}
	
	public static void main(String[] args) {
//		Keypair keypair = Sm2.generateKeyPairHex();
//		String privateKey = keypair.getPrivateKey(); // 公钥
//		String publicKey = keypair.getPublicKey(); // 私钥
//		System.out.println(privateKey);
//		System.out.println(publicKey);
		System.out.println(SmCryptoUtil.doSm4CbcEncrypt("2144cku-apk1141"));
	}
}
