package com.yfd.platform.utils.sm3;

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;

/**
 * SM3密码杂凑算法（哈希算法）
 * SM3杂凑算法是我国自主设计的密码杂凑算法。
 * 适用于商用密码应用中的数字签名和验证消息认证码的生成与验证以及随机数的生成，可满足多种密码应用的安全需求。
 * 为了保证杂凑算法的安全性，其产生的杂凑值的长度不应太短。
 * 例如MD5输出128比特杂凑值，输出长度太短，影响其安全性SHA-1算法的输出长度为160比特，SM3算法的输出长度为256比特，因此SM3算法的安全性要高于MD5算法和SHA-1算法。
 */
public class SecretCommon {

    /**
     * sm3算法加密，不可逆加密
     * @param plainText 需加密的明文字符串
     * @return 加密后固定长度64的16进制字符串
     */
    public static String encrypt(String plainText) {
        return ByteUtils.toHexString(encrypt(plainText.getBytes()));
    }

    /**
     * sm3算法加密，不可逆加密
     * @param plainByte 需加密的明文数组
     * @return 加密后固定长度64的16进制数组
     */
    public static byte[] encrypt(byte[] plainByte) {
        SM3Digest sm3Digest = new SM3Digest();
        sm3Digest.update(plainByte, 0, plainByte.length);
        byte[] digestByte = new byte[sm3Digest.getDigestSize()];
        sm3Digest.doFinal(digestByte, 0);
        return digestByte;
    }

    /**
     * sm3算法通过密钥进行加密，不可逆加密
     * @param keyText 密钥字符串
     * @param plainText 需加密的明文字符串
     * @return 加密后固定长度64的16进制字符串
     */
    public static String encryptByKey(String keyText, String plainText) {
        return ByteUtils.toHexString(encryptByKey(keyText.getBytes(), plainText.getBytes()));
    }

    /**
     * sm3算法通过密钥进行加密，不可逆加密
     * @param keyByte 密钥数组
     * @param plainByte 需加密的明文数组
     * @return 加密后固定长度64的16进制数组
     */
    public static byte[] encryptByKey(byte[] keyByte, byte[] plainByte) {
        KeyParameter keyParameter = new KeyParameter(keyByte);
        SM3Digest sm3Digest = new SM3Digest();
        HMac hMac = new HMac(sm3Digest);
        hMac.init(keyParameter);
        hMac.update(plainByte, 0, plainByte.length);
        byte[] result = new byte[hMac.getMacSize()];
        hMac.doFinal(result, 0);
        return result;
    }

}
