package com.chenyang.nse.bussiness.tools.encryption;

import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

public class SM3Utils {
   private static final String ENCODING = "UTF-8";
   private static String KEY = "";
   private static Properties props = new Properties();

   public static String encrypt(String src) throws Exception {
      return encrypt(src, KEY);
   }

   public static String encrypt(String src, String key) throws Exception {
      return ByteUtils.toHexString(getEncryptByKey(src, key));
   }

   private static byte[] getEncryptByKey(String src, String key) throws Exception {
      byte[] srcByte = src.getBytes("UTF-8");
      byte[] keyByte = key.getBytes("UTF-8");
      KeyParameter keyParameter = new KeyParameter(keyByte);
      SM3Digest sm3 = new SM3Digest();
      HMac hMac = new HMac(sm3);
      hMac.init(keyParameter);
      hMac.update(srcByte, 0, srcByte.length);
      byte[] result = new byte[hMac.getMacSize()];
      hMac.doFinal(result, 0);
      return result;
   }

   public static boolean verify(String src, String sm3HexStr) throws Exception {
      byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr);
      byte[] newHashCode = getEncryptBySrcByte(src.getBytes("UTF-8"));
      return Arrays.equals(newHashCode, sm3HashCode);
   }

   public static boolean verify(String src, String key, String sm3HexStr) throws Exception {
      byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr);
      byte[] newHashCode = getEncryptByKey(src, key);
      return Arrays.equals(newHashCode, sm3HashCode);
   }

   private static byte[] getEncryptBySrcByte(byte[] srcByte) {
      SM3Digest sm3 = new SM3Digest();
      sm3.update(srcByte, 0, srcByte.length);
      byte[] encryptByte = new byte[sm3.getDigestSize()];
      sm3.doFinal(encryptByte, 0);
      return encryptByte;
   }

   public static void main(String[] args) throws Exception {
      String srcStr = "今天天气很晴朗出去吃顿大餐GHCA-32332_@2232323";
      String key = "ghca";
      String hexStrByKey = encrypt(srcStr, key);
      System.out.println("带密钥加密后的密文：" + hexStrByKey);
      System.out.println("明文(带密钥)与密文校验结果：" + verify(srcStr, key, hexStrByKey));
      String hexStrNoKey = encrypt(srcStr);
      System.out.println("不带密钥加密后的密文：" + hexStrNoKey);
      hexStrNoKey = encrypt(srcStr);
      System.out.println("不带密钥加密后的密文：" + hexStrNoKey);
      hexStrNoKey = encrypt(srcStr, "aaaaaaaaaaaaaaaaaaaaaaaaaaa");
      System.out.println("不带密钥加密后的密文：" + hexStrNoKey);
      hexStrNoKey = encrypt(srcStr, "aaaaaaaaaaaaaaaaaaaaaaaaaaa");
      System.out.println("不带密钥加密后的密文：" + hexStrNoKey);
      srcStr = "今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗今天天气很晴朗出去吃顿大餐GHCA-32332_@2232323";
      hexStrNoKey = encrypt(srcStr, "aaaaaaaaaaaaaaaaaaaaaaaaaaa");
      System.out.println("不带密钥加密后的密文：" + hexStrNoKey);
      System.out.println("明文(不带密钥)与密文校验结果：" + verify(srcStr, hexStrNoKey));
   }

   static {
      try {
         props = PropertiesLoaderUtils.loadAllProperties("config.properties");
         KEY = props.getProperty("digestkey");
      } catch (IOException e) {
         e.printStackTrace();
      }

   }
}
