参考资料:
https://baijiahao.baidu.com/s?id=1629915330021466224&wfr=spider&for=pc
https://github.com/chenliwu/gmhelper
Maven引入加密算法库
<!-- 国密算法 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.65</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.65</version>
</dependency>
<!-- 国密算法 -->
SM3(杂凑算法)
1、SM3为杂凑算法(消息摘要,也称为散列函数)。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
2、SM3杂凑算法是我国自主设计的密码杂凑算法,适用于商用密码应用中的数字签名和验证消息认证码的生成与验证以及随机数的生成,可满足多种密码应用的安全需求。为了保证杂凑算法的安全性,其产生的杂凑值的长度不应太短,例如MD5输出128比特杂凑值,输出长度太短,影响其安全性。SHA-1算法的输出长度为160比特,SM3算法的输出长度为256比特,因此SM3算法的安全性要高于MD5算法和SHA-1算法。
3、SM3用于生成消息摘要,应用于数字签名的生成和验证。
SM3工具类代码
public class SM3Utils {
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 计算SM3摘要值
*
* @param srcData 原文
* @return 摘要值,对于SM3算法来说是32字节
*/
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 srcData 原文
* @param sm3Hash 摘要值
* @return 返回true标识验证成功,false标识验证失败
*/
public static boolean verify(byte[] srcData, byte[] sm3Hash) {
byte[] newHash = hash(srcData);
if (Arrays.equals(newHash, sm3Hash)) {
return true;
} else {
return false;
}
}
/**
* 计算SM3 Mac值
*
* @param key key值,可以是任意长度的字节数组
* @param srcData 原文
* @return Mac值,对于HMac-SM3来说是32字节
*/
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;
}
}
SM3单测代码
public class SM3UtilsTest {
public static final String KEY = "1234567812345678";
public static final String CHARSET_UTF8 = StandardCharsets.UTF_8.name();
@Test
public void testGenerateHash() throws Exception {
String data = "测试SM3杂凑算法";
// 生成消息摘要 消息摘要=SM3(原文)
byte[] signByte = SM3Utils.hash(data.getBytes(CHARSET_UTF8));
String signBase64String = B