
hutool封装国密sm2、sm3、sm4工具类
背景
平时我们的业务偶尔需要对前后端传输的参数进行加密,某些情况下(比如交付给国企单位的项目)要求一定要用国密算法来加密,这里整理了 sm2、sm3、sm4 的加解密方法封装,内部是基于 hutool 的工具再次封装,其实 hutool 内部是基于 bouncycastle 库进行封装的
引入第三方库
在 pom 中引入 hutool、bouncycastle
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
</dependency>
<!--加密工具包-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.79</version>
</dependency>
hutool 加密例子介绍
不想看例子的话,可以直接跳到 #最终封装CommonSmCryptogramUtils,复制最终的封装类到你的项目中用
生成密钥的工具方法
生成 SM2 密钥对
生成 SM2 密钥对,用到了 BC 库的方法
/**
* 生成sm2密钥对
*/
@Test
public void generateSm2KeyPair() {
SM2 sm2 = new SM2();
ECPublicKey publicKey = (ECPublicKey) sm2.getPublicKey();
ECPrivateKey privateKey = (ECPrivateKey) sm2.getPrivateKey();
byte[] publicKeyBytes = publicKey.getQ().getEncoded(false);
String publicKeyHex = HexUtil.encodeHexStr(publicKeyBytes);
String privateKeyHex = privateKey.getD().toString(16);
// BigInteger转成16进制时,不一定长度为64,如果私钥长度小于64,则在前方补0
StringBuilder privateKey64 = new StringBuilder(privateKeyHex);
while (privateKey64.length() < 64) {
privateKey64.insert(0, "0");
}
privateKeyHex = privateKey64.toString();
System.out.println("sm2PublicKey: " + publicKeyHex);
System.out.println("sm2PrivateKey: " + privateKeyHex);
}
生成 SM4 密钥和 IV 值
SM4 密钥和 iv 值,其实只是普通的 16 字节的数据,随机生成即可
/**
* 生成sm4秘钥
*/
@Test
public void generateSm4Key() {
System.out.println("sm4Key: " + generateRandomHexStr(16));
}
/**
* 生成sm4的iv
*/
@Test
public static String generateSm4Iv() {
System.out.println("sm4Iv: " + generateRandomHexStr(16));
}
/**
* 随机生成指定字节数的十六进制编码
* @param byteCount 字节数
* @return 十六进制编码
*/
public String generateRandomHexStr(int byteCount) {
SecureRandom random= new SecureRandom();
byte[] bytes = new byte[byteCount];
random.nextBytes(bytes);
return HexUtil.encodeHexStr(bytes);
}
SM2
加解密
@Test
public void testHutoolSm2() {
String text = "admin123";
{
// 构造函数里什么都不传,则是使用它内部随机生成的密钥对
System.out.println("-------------- 构造函数里什么都不传,则是使用它内部随机生成的密钥对 ---------------");
SM2 sm2 = new SM2();
String encrypt = HexUtil.encodeHexStr(sm2.encrypt(text.getBytes()));
System.out.println("1)密文16进制字符串:" + encrypt);
System.out.println("1)解密后明文字符串:" + new String(sm2.decrypt(HexUtil.decodeHex(encrypt))));
System.out.println();
}
{
// 使用指定的公私钥(密钥对使用上面说的生成sm2密钥对的方法来生成)
String publicKey = "04349bdbf50cda0abf46692ed5eecca93ee4efed4478f958b1bd793bae501fe6205d8e9234781113715feb05ee6c0e12eb280409f3c4ddcc769283be66adb46921";
String privateKey = "67eb8864b70582a60b2f1250424d4fbedfb8ec0a7bf5523095df14864271d013";
// 公私钥都传进去,可以加密,也可以解密
{
System.out.println("-------------- 公私钥都传进去,可以加密,也可以解密 ---------------");
SM2 sm2 = new SM2(privateKey, publicKey);
String encrypt = HexUtil.encodeHexStr(sm2.encrypt(text.getBytes()));
System.out.println("密文16进制字符串:" + encrypt);
System.out.println("解密后明文字符串:" + new String(sm2.decrypt(HexUtil.decodeHex(encrypt))));
System.out.println();
}
// 只传公钥,只能加密
{
System.out.println("-------------- 只传公钥,只能加密 ---------------");
SM2 sm2 = new SM2(null, publicKey);
String encrypt = HexUtil.encodeHexStr(sm2.encrypt(text.getBytes()));
System.out.println("密文16进制字符串:" + encrypt);
System.out.println();
}
// 只传私钥,只能解密
{
System.out.println("-------------- 只传私钥,只能解密 ---------------");
SM2 sm2 = new SM2(privateKey, null);
String encrypt = "04787e2b3b059c5b606ff4cc4b2a6cf9bcb6758808e81f2ebc612586ee7907db5c9089010e12df9cc99cc1ffa3ae99ae06bde8102182e557374d27b1af9ee7493da5bb023a636f64ded0e9744d212069b3a2bf34e496b57f6761b1c3c76f3d127deddec674805de620";
System.out.println("密文16进制字符串:" + encrypt);
System.out.println("解密后明文字符串:" + new String(sm2.decrypt(HexUtil.decodeHex(encrypt))));
System.out.println();
}
}
}
加签验签
@Test
public void testHutoolSm2Sign() {
String text = "admin123";
{
// 使用指定的公私钥
String publicKey = "04349bdbf50cda0abf46692ed5eecca93ee4efed4478f958b1bd793bae501fe6205d8e9234781113715feb05ee6c0e12eb280409f3c4ddcc769283be66adb46921";
String privateKey = "67eb8864b70582a60b2f1250424d4fbedfb8ec0a7bf5523095df14864271d013";
// 使用私钥加签,公钥验签
{
System.out.println("-------------- 使用私钥加签,公钥验签 ---------------");
// 也可以单独传入私钥只做加签,或者单独传入公钥只做验签
SM2 sm2 = new SM2(privateKey, publicKey);
String signHex = HexUtil.encodeHexStr(sm2.sign(text.getBytes()));
System.out.println("签名16进制字符串:" + signHex);
System.out.println("验签结果:" + sm2.verify(text.getBytes(), HexUtil.decodeHex(signHex)));
}
}
}
SM3
SM3 生成摘要
@Test
public void testHutoolSm3() {
String text = "admin123";
// 不加salt
{
SM3 sm3 = new SM3();
System.out.println("不加salt: " + sm3.digestHex(text.getBytes()));
}
// 加salt
{
String salt = "this is salt";
SM3 sm3 = new SM3(salt.getBytes());
System.out.println("加salt: " + sm3.digestHex(text.getBytes()));
}
}
SM4
SM4 可以设置模式(CBC、ECB 等等)、填充方式(PKCS5Padding、ZeroPadding 等等)
下面以 CBC/PKCS5Padding 为例子
@Test
public void testHutoolSm4() {
// 密钥和iv使用前面说的生成方式生成
String key = "c88d7433938f213105f546e52eb86f3a";
String iv = "885fa5d11189460386aec69233ccb5f3";
String text = "admin123";
SM4 sm4 = new SM4(Mode.CBC, Padding.PKCS5Padding, HexUtil.decodeHex(key), HexUtil.decodeHex(iv));
String encodeHexStr = HexUtil.encodeHexStr(sm4.encrypt(text.getBytes()));
System.out.println("密文: " + encodeHexStr);
System.out.println("明文: " + new String(sm4.decrypt(HexUtil.decodeHex(encodeHexStr))));
}
最终封装CommonSmCryptogramUtils
定义密钥对类
package com.kk.utils;
import lombok.Data;
@Data
public class Keypair {
protected String privateKey;
protected String publicKey;
public Keypair() {
}
public Keypair(String privateKey, String publicKey) {
this.privateKey = privateKey;
this.publicKey = publicKey;
}
public String toString() {
return "Keypair{\n privateKey: " + this.privateKey + "\n publicKey: " + this.publicKey + "\n}";
}
}
封装工具类
下面 CommonSmCryptogramUtil 类中的 SM2_PRIVATE_KEY、SM2_PUBLIC_KEY、SM4_KEY、SM4_IV 这几个默认密钥要按照注释里写的方法来生成哦
package com.kk.utils;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.digest.SM3;
import cn.hutool.crypto.symmetric.SM4;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.signers.DSAEncoding;
import org.bouncycastle.crypto.signers.StandardDSAEncoding;
import org.bouncycastle.jce.interfaces.ECPrivateKey;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import java.io.InputStream;
import java.security.SecureRandom;
public class CommonSmCryptogramUtil {
// 可以调用generateSm2KeyPair()方法来生成
public static final String SM2_PRIVATE_KEY = "sm2私钥";
public static final String SM2_PUBLIC_KEY = "sm2公钥";
// 可以调用generateSm4Key()生成
public static final String SM4_KEY = "sm4密钥";
// 可以调用generateSm4Iv()生成
public static final String SM4_IV = "sm4 iv";
public static SecureRandom RANDOM = new SecureRandom();
/**
* 生成sm2密钥对
* 公钥:keypair.getPublicKey()
* 私钥:keypair.getPrivateKey()
*
* @return 密钥对
*/
public static Keypair generateSm2KeyPair() {
SM2 sm2 = new SM2();
ECPublicKey publicKey = (ECPublicKey) sm2.getPublicKey();
ECPrivateKey privateKey = (ECPrivateKey) sm2.getPrivateKey();
byte[] publicKeyBytes = publicKey.getQ().getEncoded(false);
String publicKeyHex = HexUtil.encodeHexStr(publicKeyBytes);
String privateKeyHex = privateKey.getD().toString(16);
// BigInteger转成16进制时,不一定长度为64,如果私钥长度小于64,则在前方补0
StringBuilder privateKey64 = new StringBuilder(privateKeyHex);
while (privateKey64.length() < 64) {
privateKey64.insert(0, "0");
}
privateKeyHex = privateKey64.toString();
return new Keypair(privateKeyHex, publicKeyHex);
}
/**
* 生成sm4秘钥
*
* @return 秘钥十六进制编码
*/
public static String generateSm4Key() {
return generateRandomHexStr(16);
}
/**
* 生成sm4的iv
*
* @return iv十六进制编码
*/
public static String generateSm4Iv() {
return generateRandomHexStr(16);
}
/**
* 随机生成指定字节数的十六进制编码
*
* @param byteCount 字节数
* @return 十六进制编码
*/
public static String generateRandomHexStr(int byteCount) {
byte[] bytes = new byte[byteCount];
RANDOM.nextBytes(bytes);
return HexUtil.encodeHexStr(bytes);
}
/**
* sm2默认公钥加密
*
* @return 秘文十六进制编码
*/
public static String sm2Encrypt(String str) {
return sm2Encrypt(str, SM2_PUBLIC_KEY);
}
/**
* sm2默认公钥加密
*
* @return 秘文十六进制编码
*/
public static String sm2EncryptFromBytes(byte[] data) {
return sm2EncryptFromBytes(data, SM2_PUBLIC_KEY);
}
/**
* sm2公钥加密
*
* @return 秘文十六进制编码
*/
public static String sm2Encrypt(String str, String publicKey) {
if (str == null || str.isEmpty()) {
return str;
}
return sm2EncryptFromBytes(str.getBytes(), publicKey);
}
/**
* sm2公钥加密
*
* @return 秘文十六进制编码
*/
public static String sm2EncryptFromBytes(byte[] data, String publicKey) {
return sm2EncryptFromBytes(data, publicKey, SM2Engine.Mode.C1C3C2, new SM3Digest());
}
/**
* sm2公钥加密
*
* @return 秘文十六进制编码
*/
public static String sm2EncryptFromBytes(byte[] data, String publicKey, SM2Engine.Mode mode, Digest digest) {
if (data == null || data.length == 0) {
return data == null ? null : "";
}
SM2 sm2 = new SM2(null, publicKey);
sm2.setMode(mode);
sm2.setDigest(digest);
try {
return HexUtil.encodeHexStr(sm2.encrypt(data));
} catch (Exception e) {
throw new RuntimeException("SM2加密失败", e);
}
}
/**
* sm2用默认私钥解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static String sm2Decrypt(String hexStr) {
return sm2Decrypt(hexStr, SM2_PRIVATE_KEY);
}
/**
* sm2用默认私钥解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static byte[] sm2DecryptToBytes(String hexStr) {
return sm2DecryptToBytes(hexStr, SM2_PRIVATE_KEY);
}
/**
* sm2私钥解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static String sm2Decrypt(String hexStr, String privateKey) {
if (hexStr == null || hexStr.isEmpty()) {
return null;
}
return new String(sm2DecryptToBytes(hexStr, privateKey));
}
/**
* sm2私钥解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static byte[] sm2DecryptToBytes(String hexStr, String privateKey) {
return sm2DecryptToBytes(hexStr, privateKey, SM2Engine.Mode.C1C3C2, new SM3Digest());
}
/**
* sm2私钥解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static byte[] sm2DecryptToBytes(String hexStr, String privateKey, SM2Engine.Mode mode, Digest digest) {
if (hexStr == null || hexStr.isEmpty()) {
return null;
}
// 前端使用的是sm-crypto库,秘文不会有04开头,得加上
if (!hexStr.startsWith("04")) {
hexStr = "04" + hexStr;
}
SM2 sm2 = new SM2(privateKey, null);
sm2.setMode(mode);
sm2.setDigest(digest);
try {
return sm2.decrypt(HexUtil.decodeHex(hexStr));
} catch (Exception e) {
throw new RuntimeException("SM2解密失败", e);
}
}
/**
* sm4 cbc 用默认秘钥加密
*
* @return 秘文十六进制编码
*/
public static String sm4CbcEncrypt(String str) {
return sm4CbcEncrypt(str, SM4_KEY, SM4_IV);
}
/**
* sm4 cbc 用默认秘钥加密
*
* @return 秘文十六进制编码
*/
public static String sm4CbcEncryptFromBytes(byte[] data) {
return sm4CbcEncryptFromBytes(data, SM4_KEY, SM4_IV);
}
/**
* sm4 cbc 加密
*
* @return 秘文十六进制编码
*/
public static String sm4CbcEncrypt(String str, String keyHex, String ivHex) {
if (str == null) {
return null;
}
return sm4CbcEncryptFromBytes(str.getBytes(), keyHex, ivHex);
}
/**
* sm4 cbc 加密
*
* @return 秘文十六进制编码
*/
public static String sm4CbcEncryptFromBytes(byte[] data, String keyHex, String ivHex) {
return sm4EncryptFromBytes(data, keyHex, ivHex, Mode.CBC.name(), Padding.PKCS5Padding.name());
}
/**
* sm4 cbc 加密
*
* @param mode 看{@link Mode}
* @param padding 看{@link Padding}
* @return 秘文十六进制编码
*/
public static String sm4EncryptFromBytes(byte[] data, String keyHex, String ivHex, String mode, String padding) {
if (data == null) {
return null;
}
SM4 sm4 = new SM4(mode, padding, HexUtil.decodeHex(keyHex), StrUtil.isBlank(ivHex) ? null : HexUtil.decodeHex(ivHex));
try {
return HexUtil.encodeHexStr(sm4.encrypt(data));
} catch (Exception e) {
throw new RuntimeException("SM4 CBC加密失败", e);
}
}
/**
* sm4 cbc 用默认秘钥解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static String sm4CbcDecrypt(String hexStr) {
return sm4CbcDecrypt(hexStr, SM4_KEY, SM4_IV);
}
/**
* sm4 cbc 用默认秘钥解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static byte[] sm4CbcDecryptToBytes(String hexStr) {
return sm4CbcDecryptToBytes(hexStr, SM4_KEY, SM4_IV);
}
/**
* sm4 cbc 解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static String sm4CbcDecrypt(String hexStr, String keyHex, String ivHex) {
if (hexStr == null || hexStr.isEmpty()) {
return null;
}
return new String(sm4CbcDecryptToBytes(hexStr, keyHex, ivHex));
}
/**
* sm4 cbc 解密
*
* @param hexStr 秘文十六进制编码
* @return 明文
*/
public static byte[] sm4CbcDecryptToBytes(String hexStr, String keyHex, String ivHex) {
return sm4DecryptToBytes(hexStr, keyHex, ivHex, Mode.CBC.name(), Padding.PKCS5Padding.name());
}
/**
* sm4 cbc 解密
*
* @param hexStr 秘文十六进制编码
* @param mode 看{@link Mode}
* @param padding 看{@link Padding}
* @return 明文
*/
public static byte[] sm4DecryptToBytes(String hexStr, String keyHex, String ivHex, String mode, String padding) {
if (hexStr == null || hexStr.isEmpty()) {
return null;
}
SM4 sm4 = new SM4(mode, padding, HexUtil.decodeHex(keyHex), StrUtil.isBlank(ivHex) ? null : HexUtil.decodeHex(ivHex));
try {
return sm4.decrypt(HexUtil.decodeHex(hexStr));
} catch (Exception e) {
throw new RuntimeException("SM4 CBC解密失败", e);
}
}
/**
* sm2用默认私钥签名
*
* @return 签名十六进制编码
*/
public static String sm2Signature(String str) {
return sm2Signature(str, SM2_PRIVATE_KEY);
}
/**
* sm2私钥签名
*
* @return 签名十六进制编码
*/
public static String sm2Signature(String str, String privateKey) {
return sm2Signature(str, privateKey, StandardDSAEncoding.INSTANCE, new SM3Digest());
}
/**
* sm2私钥签名
*
* @return 签名十六进制编码
*/
public static String sm2Signature(String str, String privateKey, DSAEncoding encoding, Digest digest) {
if (str == null) {
return null;
}
SM2 sm2 = new SM2(privateKey, null);
sm2.setEncoding(encoding);
sm2.setDigest(digest);
try {
return HexUtil.encodeHexStr(sm2.sign(str.getBytes()));
} catch (Exception e) {
throw new RuntimeException("SM2签名失败", e);
}
}
/**
* sm2用默认公钥验证签名结果
*/
public static boolean sm2VerifySignature(String originalStr, String signHexStr) {
return sm2VerifySignature(originalStr, signHexStr, SM2_PUBLIC_KEY);
}
/**
* sm2验证签名结果
*/
public static boolean sm2VerifySignature(String originalStr, String signHexStr, String publicKey) {
return sm2VerifySignature(originalStr, signHexStr, publicKey, StandardDSAEncoding.INSTANCE, new SM3Digest());
}
/**
* sm2验证签名结果
*/
public static boolean sm2VerifySignature(String originalStr, String signHexStr, String publicKey, DSAEncoding encoding, Digest digest) {
if (originalStr == null || signHexStr == null || signHexStr.isEmpty()) {
return false;
}
SM2 sm2 = new SM2(null, publicKey);
sm2.setEncoding(encoding);
sm2.setDigest(digest);
try {
return sm2.verify(originalStr.getBytes(), HexUtil.decodeHex(signHexStr));
} catch (Exception e) {
throw new RuntimeException("SM2验证签名失败", e);
}
}
/**
* sm3取哈希
*
* @return 摘要十六进制编码
*/
public static String sm3HashValue(String dataStr) {
if (dataStr == null) {
return null;
}
SM3 sm3 = new SM3();
try {
return sm3.digestHex(dataStr.getBytes());
} catch (Exception e) {
throw new RuntimeException("SM3计算摘要失败", e);
}
}
/**
* sm3取哈希
*
* @return 摘要十六进制编码
*/
public static String sm3HashValue(byte[] data) {
if (data == null) {
return null;
}
SM3 sm3 = new SM3();
try {
return sm3.digestHex(data);
} catch (Exception e) {
throw new RuntimeException("SM3计算摘要失败", e);
}
}
/**
* sm3取哈希
*
* @param dataStr 字符串数据
* @param salt 添加的盐值
* @return 摘要十六进制编码
*/
public static String sm3HashValue(String dataStr, byte[] salt) {
if (dataStr == null) {
return null;
}
SM3 sm3 = new SM3(salt);
try {
return sm3.digestHex(dataStr.getBytes());
} catch (Exception e) {
throw new RuntimeException("SM3计算摘要失败", e);
}
}
/**
* sm3取哈希
*
* @param salt 添加的盐值
* @return 摘要十六进制编码
*/
public static String sm3HashValue(InputStream inputStream, byte[] salt) {
SM3 sm3 = new SM3(salt);
try {
return sm3.digestHex(inputStream);
} catch (Exception e) {
throw new RuntimeException("SM3计算摘要失败", e);
}
}
}
工具类使用例子
生成 SM2 密钥对
@Test
public void testGenSm2Keypair() {
Keypair keypair = CommonSmCryptogramUtil.generateSm2KeyPair();
System.out.println("sm2PublicKey: " + keypair.getPublicKey());
System.out.println("sm2PrivateKey: " + keypair.getPrivateKey());
}
生成 SM4 密钥和 IV
@Test
public void testGenSm4Key() {
System.out.println("sm4Key: " + CommonSmCryptogramUtil.generateSm4Key());
System.out.println("sm4Iv: " + CommonSmCryptogramUtil.generateSm4Iv());
}
测试 SM2 加解密、加签验签
@Test
public void testSm2() {
String val = "admin";
{
// 默认使用 c1c3c2模式,sm3做摘要
System.out.println("---------------- c1c3c2+sm3 加解密 -------------------");
String sm2EncryptVal = CommonSmCryptogramUtil.sm2Encrypt(val);
System.out.println("(c1c3c2+sm3)sm2加密:" + sm2EncryptVal);
System.out.println("(c1c3c2+sm3)sm2解密:" + CommonSmCryptogramUtil.sm2Decrypt(sm2EncryptVal));
System.out.println();
// 默认使用 sm3做摘要,ASN1编码方式
System.out.println("---------------- ASN1编码 加签验签 -------------------");
String sm2SignatureVal = CommonSmCryptogramUtil.sm2Signature(val);
System.out.println("(ASN1)sm2签名:" + sm2SignatureVal);
System.out.println("(ASN1)sm2验证签名:" + CommonSmCryptogramUtil.sm2VerifySignature(val, sm2SignatureVal));
System.out.println();
}
{
// 使用c1c2c3模式
System.out.println("---------------- c1c2c3+sm3 加解密 -------------------");
String sm2EncryptVal = CommonSmCryptogramUtil.sm2EncryptFromBytes(val.getBytes(), CommonSmCryptogramUtil.SM2_PUBLIC_KEY, SM2Engine.Mode.C1C2C3, new SM3Digest());
System.out.println("(c1c2c3+sm3)sm2加密:" + sm2EncryptVal);
System.out.println("(c1c2c3+sm3)sm2解密:" + new String(CommonSmCryptogramUtil.sm2DecryptToBytes(sm2EncryptVal, CommonSmCryptogramUtil.SM2_PRIVATE_KEY, SM2Engine.Mode.C1C2C3, new SM3Digest())));
System.out.println();
// 使用sm3做摘要,Plain编码方式
System.out.println("---------------- Plain编码 加签验签 -------------------");
String sm2SignatureVal = CommonSmCryptogramUtil.sm2Signature(val, CommonSmCryptogramUtil.SM2_PRIVATE_KEY, PlainDSAEncoding.INSTANCE, new SM3Digest());
System.out.println("(Plain)sm2签名:" + sm2SignatureVal);
System.out.println("(Plain)sm2验证签名:" + CommonSmCryptogramUtil.sm2VerifySignature(val, sm2SignatureVal, CommonSmCryptogramUtil.SM2_PUBLIC_KEY, PlainDSAEncoding.INSTANCE, new SM3Digest()));
}
}
测试 SM3 生成摘要
@Test
public void testSm3() {
String val = "admin";
System.out.println("sm3哈希:" + CommonSmCryptogramUtil.sm3HashValue(val));
System.out.println("sm3哈希(加salt): + " + CommonSmCryptogramUtil.sm3HashValue(val, "this is salt".getBytes()));
}
测试 SM4 加解密
@Test
public void testSm4() {
String val = "admin";
{
// 默认是 CBC/PKCS5Padding
System.out.println("------------------- CBC/PKCS5Padding -----------------");
String sm4EncryptVal = CommonSmCryptogramUtil.sm4CbcEncrypt(val);
System.out.println("sm4加密:" + sm4EncryptVal);
System.out.println("sm4解密:" + CommonSmCryptogramUtil.sm4CbcDecrypt(sm4EncryptVal));
System.out.println();
}
{
System.out.println("------------------- CBC/PKCS7Padding -----------------");
String sm4EncryptVal = CommonSmCryptogramUtil.sm4EncryptFromBytes(val.getBytes(), CommonSmCryptogramUtil.SM4_KEY, CommonSmCryptogramUtil.SM4_IV, Mode.CBC.name(), "PKCS7Padding");
System.out.println("sm4加密:" + sm4EncryptVal);
System.out.println("sm4解密:" + new String(CommonSmCryptogramUtil.sm4DecryptToBytes(sm4EncryptVal, CommonSmCryptogramUtil.SM4_KEY, CommonSmCryptogramUtil.SM4_IV, Mode.CBC.name(), "PKCS7Padding")));
System.out.println();
}
{
System.out.println("------------------- ECB/PKCS7Padding (注意:ECB模式不需要iv) -----------------");
String sm4EncryptVal = CommonSmCryptogramUtil.sm4EncryptFromBytes(val.getBytes(), CommonSmCryptogramUtil.SM4_KEY, null, Mode.ECB.name(), "PKCS7Padding");
System.out.println("sm4加密:" + sm4EncryptVal);
System.out.println("sm4解密:" + new String(CommonSmCryptogramUtil.sm4DecryptToBytes(sm4EncryptVal, CommonSmCryptogramUtil.SM4_KEY, null, Mode.ECB.name(), "PKCS7Padding")));
System.out.println();
}
}
本文是原创文章,采用 CC 4.0 BY-SA 协议,完整转载请注明来自 KK元空间
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果