Heaven helps those who help themselves
资深码农+深耕理财=财富自由
欢迎关注

java sm3加密算法

Created by Marydon on 2018-07-13 09:38

1.准备工作

  所需jar包:

  bcprov-jdk15on-1.59.jar

  commons-lang3-3.1.jar

  20200901

  对应的maven依赖

1
2
3
4
5
6
<!--sm3,sm4加密算法-->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.66</version>
</dependency>  
1
2
3
4
5
6
7
8
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;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * sm3加密算法工具类
 * @explain 加密与加密结果验证(不可逆算法)
 * @author Marydon
 * @creationTime 2018年7月5日上午10:01:24
 * @version 1.0
 * @since
 * @email marydon20170307@163.com
 */
public class Sm3Utils {
 
    private static final String ENCODING = "UTF-8";
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
} 

2.SM3加密

  方式一:不提供密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * sm3算法加密
 * @explain
 * @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数组
 * @explain 生成对应的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;
} 

  方式二:自定义密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
 * 通过密钥进行加密
 * @explain 指定密钥进行加密
 * @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;
}  

3.加密数据校验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * 判断源数据与加密数据是否一致
 * @explain 通过验证原数组和生成的hash数组是否为同一数组,验证2者是否为同一数据
 * @param srcStr
 *            原字符串
 * @param sm3HexString
 *            16进制字符串
 * @return 校验结果
 */
public static boolean verify(String srcStr, String sm3HexString) {
    boolean flag = false;
    try {
        byte[] srcData = srcStr.getBytes(ENCODING);
        byte[] sm3Hash = ByteUtils.fromHexString(sm3HexString);
        byte[] newHash = hash(srcData);
        if (Arrays.equals(newHash, sm3Hash))
            flag = true;
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return flag;
} 

4.测试

复制代码
public static void main(String[] args) {
    // 测试二:json
    String json = "{\"name\":\"Marydon\",\"website\":\"http://www.cnblogs.com/Marydon20170307\"}";
    String hex = Sm3Utils.encrypt(json);
    System.out.println(hex);// 0b0880f6f2ccd817809a432420e42b66d3772dc18d80789049d0f9654efeae5c
    // 验证加密后的16进制字符串与加密前的字符串是否相同
    boolean flag = Sm3Utils.verify(json, hex);
    System.out.println(flag);// true

}
复制代码

 

与君共勉:最实用的自律是攒钱,最养眼的自律是健身,最健康的自律是早睡,最改变气质的自律是看书,最好的自律是经济独立 。

您的一个点赞,一句留言,一次打赏,就是博主创作的动力源泉!

↓↓↓↓↓↓写的不错,对你有帮助?赏博主一口饭吧↓↓↓↓↓↓

点赞(0)

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部