SM3-雜湊算法,單向散列函數(單向性,不可逆)


示例代碼:

1、SM3工具類

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Arrays;

public class Sm3Utils {

    private static final String ENCODING = "UTF-8";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 不提供密鑰
     * sm3算法加密
     * @param paramStr  待加密字符串
     * @return 返回加密后,固定長度=32的16進制字符串
     */
    public static String encrypt(String paramStr) {
        // 將返回的hash值轉換成16進制字符串
        String resultHexString = "";
        try {
            // 將字符串轉換成byte數組
            byte[] srcData = paramStr.getBytes(ENCODING);
            // 調用hash
            byte[] resultHash = hash(srcData);
            // 將返回的hash值轉換成16進制字符串
            resultHexString = ByteUtils.toHexString(resultHash);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return resultHexString;
    }

    /**
     * 返回長度=32的byte數組
     * 生成對應的hash值
     * @param srcData
     * @return
     */
    public static byte[] hash(byte[] srcData) {
        //摘要加密
        SM3Digest digest = new SM3Digest();
        //使用指定的數組更新摘要
        digest.update(srcData,0,srcData.length);
        //獲取摘要的長度
        byte[] hash = new byte[digest.getDigestSize()];
        digest.doFinal(hash,0);
        return hash;
    }

    /**
     * 通過密鑰進行加密
     * 指定密鑰進行加密
     * @param key 密鑰
     * @param srcData 被加密的byte數組
     * @return
     */
    public static byte[] hmac(byte[] key,byte[] srcData) {
        KeyParameter keyParameter = new KeyParameter(key);
        SM3Digest digest = new SM3Digest();
        HMac mac = new HMac(digest);
        mac.init(keyParameter);
        mac.update(srcData,0,srcData.length);
        byte[] result = new byte[mac.getMacSize()];
        mac.doFinal(result,0);
        return result;
    }

    /**
     * 判斷源數據與加密數據是否一致
     * 通過驗證原數組和生成的hash數組是否為同一數組,驗證兩者是否為同意數據
     * @param srcStr 源字符串
     * @param sm3HexString 16進制字符串
     * @return 校驗結構
     */
    public static boolean verify(String srcStr,String sm3HexString) {

        boolean flag = false;
        try {
            //原字符串
            byte[] srcData  = srcStr.getBytes(ENCODING);
            //16進制轉為數組
            byte[] sm3Hash = ByteUtils.fromHexString(sm3HexString);
            //通過摘要加密生成新的hash數組
            byte[] newHash = hash(srcData);
            if (Arrays.equals(newHash,sm3Hash))
                flag = true;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return flag;
    }
}

2、測試

import com.xdh.demo.sm3.Sm3Utils;

public class Sm3UtilsTest {
    public static void main(String[] args) {
        //JSON串加密
        String json = "{\"name\":\"xiatian\",\"website\":\"http://www.bai.com\"}";
        String hex = Sm3Utils.encrypt(json);
        System.out.println(hex);   //fe2547ca491088e5c5d1664b049558de896db8ceed65044bd6212f4393d2d7ce

        //單個字符串加密
        String str = "123456";
        //加密之后轉為16進制字符串
        String mm = Sm3Utils.encrypt(str);
        System.out.println("加密后:" + mm);   //加密后:207cf410532f92a47dee245ce9b11ff71f578ebd763eb3bbea44ebd043d018fb

        boolean flag = Sm3Utils.verify(str,mm);
        System.out.println(flag);   //true
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM