java sm3加密算法实现
CreationTime--2018年7月13日09点28分
Author:Marydon
1.准备工作
所需jar包:
bcprov-jdk15on-1.59.jar
commons-lang3-3.1.jar
1import org.bouncycastle.crypto.digests.SM3Digest; 2import org.bouncycastle.crypto.macs.HMac; 3import org.bouncycastle.crypto.params.KeyParameter; 4import org.bouncycastle.jce.provider.BouncyCastleProvider; 5import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; 6import java.io.UnsupportedEncodingException; 7import java.security.Security; 8import java.util.Arrays; 9 10/** 11 * sm3加密算法工具类 12 * @explain 加密与加密结果验证(不可逆算法) 13 * @author Marydon 14 * @creationTime 2018年7月5日上午10:01:24 15 * @version 1.0 16 * @since 17 * @email marydon20170307@163.com 18 */ 19public class Sm3Utils { 20 21 private static final String ENCODING = "UTF-8"; 22 static { 23 Security.addProvider(new BouncyCastleProvider()); 24 } 25}
2.SM3加密
方式一:不提供密钥
1/** 2 * sm3算法加密 3 * @explain 4 * @param paramStr 5 * 待加密字符串 6 * @return 返回加密后,固定长度=32的16进制字符串 7 */ 8public static String encrypt(String paramStr){ 9 // 将返回的hash值转换成16进制字符串 10 String resultHexString = ""; 11 try { 12 // 将字符串转换成byte数组 13 byte[] srcData = paramStr.getBytes(ENCODING); 14 // 调用hash() 15 byte[] resultHash = hash(srcData); 16 // 将返回的hash值转换成16进制字符串 17 resultHexString = ByteUtils.toHexString(resultHash); 18 } catch (UnsupportedEncodingException e) { 19 e.printStackTrace(); 20 } 21 return resultHexString; 22} 23 24/** 25 * 返回长度=32的byte数组 26 * @explain 生成对应的hash值 27 * @param srcData 28 * @return 29 */ 30public static byte[] hash(byte[] srcData) { 31 SM3Digest digest = new SM3Digest(); 32 digest.update(srcData, 0, srcData.length); 33 byte[] hash = new byte[digest.getDigestSize()]; 34 digest.doFinal(hash, 0); 35 return hash; 36}
方式二:自定义密钥
1/** 2 * 通过密钥进行加密 3 * @explain 指定密钥进行加密 4 * @param key 5 * 密钥 6 * @param srcData 7 * 被加密的byte数组 8 * @return 9 */ 10public static byte[] hmac(byte[] key, byte[] srcData) { 11 KeyParameter keyParameter = new KeyParameter(key); 12 SM3Digest digest = new SM3Digest(); 13 HMac mac = new HMac(digest); 14 mac.init(keyParameter); 15 mac.update(srcData, 0, srcData.length); 16 byte[] result = new byte[mac.getMacSize()]; 17 mac.doFinal(result, 0); 18 return result; 19}
3.加密数据校验
1/** 2 * 判断源数据与加密数据是否一致 3 * @explain 通过验证原数组和生成的hash数组是否为同一数组,验证2者是否为同一数据 4 * @param srcStr 5 * 原字符串 6 * @param sm3HexString 7 * 16进制字符串 8 * @return 校验结果 9 */ 10public static boolean verify(String srcStr, String sm3HexString) { 11 boolean flag = false; 12 try { 13 byte[] srcData = srcStr.getBytes(ENCODING); 14 byte[] sm3Hash = ByteUtils.fromHexString(sm3HexString); 15 byte[] newHash = hash(srcData); 16 if (Arrays.equals(newHash, sm3Hash)) 17 flag = true; 18 } catch (UnsupportedEncodingException e) { 19 e.printStackTrace(); 20 } 21 return flag; 22}
4.测试
1public static void main(String[] args) { 2 // 测试二:json 3 String json = "{\"name\":\"Marydon\",\"website\":\"http://www.cnblogs.com/Marydon20170307\"}"; 4 String hex = Sm3Utils.encrypt(json); 5 System.out.println(hex);// 0b0880f6f2ccd817809a432420e42b66d3772dc18d80789049d0f9654efeae5c 6 // 验证加密后的16进制字符串与加密前的字符串是否相同 7 boolean flag = Sm3Utils.verify(json, hex); 8 System.out.println(flag);// true 9 10}