在商用密码体系中,SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,其算法公开。据国家密码管理局表示,其安全性及效率与SHA-256相当。
需要引入如下坐标依赖:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
自定义密钥加密及校验
加密
private static final String ENCODING = "UTF-8";
public static String encrypt(String src, String key) throws Exception {
return ByteUtils.toHexString(getEncryptByKey(src, key));
}
public static byte[] getEncryptByKey(String src, String key) throws Exception {
byte[] srcByte = src.getBytes(ENCODING);
byte[] keyByte = key.getBytes(ENCODING);
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 key, String sm3HexStr) throws Exception {
byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr);
byte[] newHashCode = getEncryptByKey(src, key);
return Arrays.equals(newHashCode, sm3HashCode);
}
无密钥的加密及校验
加密
public static String encrypt(String src) {
return ByteUtils.toHexString(getEncryptBySrcByte(src.getBytes()));
}
public 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 boolean verify(String src, String sm3HexStr) throws Exception {
byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr);
byte[] newHashCode = getEncryptBySrcByte(src.getBytes(ENCODING));
return Arrays.equals(newHashCode, sm3HashCode);
}
测试验证
public static void main(String[] args) throws Exception {
String srcStr = "今天天气很晴朗";
String key = "zjqzjq";
String hexStrByKey = SM3Utils.encrypt(srcStr, key);
System.out.println("带密钥加密后的密文:" + hexStrByKey);
System.out.println("明文(带密钥)与密文校验结果:" + SM3Utils.verify(srcStr, key, hexStrByKey));
String hexStrNoKey = SM3Utils.encrypt(srcStr);
System.out.println("不带密钥加密后的密文:" + hexStrNoKey);
System.out.println("明文(不带密钥)与密文校验结果:" + SM3Utils.verify(srcStr, hexStrNoKey));
}
结果输出如下:
|