简介(必看)
国密sm2、sm4都是可以加解密的,sm3是单向加密,是无法解密的
sm2加密和解密是不同的秘钥,需要提前生成一对公钥和私钥,公钥用来加密,私钥用来解密
sm4的加解密用的是一样的秘钥
国密sm2
sm2加解密方式:需要提前生成好一对公钥和私钥,然后加密的时候,用公钥进行加密,解密的时候,用私钥进行解密
java端
添加依赖
<!--SM2加密-->
<dependency>
<groupId></groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.72</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<!--hutool-->
<dependency>
<groupId></groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
生成公钥和私钥
SM2 sm2 = SmUtil.sm2();
String privateKey = ((()));
String publicKey = (((BCECPublicKey) ()).getQ().getEncoded(false));
加解密工具类
import ;
import ;
/**
* 加解密工具类
*
* @author 猴哥
*/
public class Sm2Util {
/**
* 加密
*
* @param publicKey 公钥
* @param data 明文
* @return 密文
*/
public static String encrypt(String publicKey, String data) {
return SmUtil.sm2(null, publicKey)
.encryptHex((), )
// 加密后,密文前面会有04,需要去掉
.substring(2);
}
/**
* 解密
*
* @param privateKey 私钥
* @param data 密文
* @return 明文
*/
public static String decrypt(String privateKey, String data) {
// 前端加密是没有04的,所以解析的时候要加04
data = "04" + data;
return SmUtil.sm2(privateKey, null)
.decryptStr(data, );
}
}
vue端
添加依赖
npm install sm-crypto --save
生成公钥和私钥
const sm2 = require('sm-crypto').sm2
let keypair = ();
// 公钥
let publicKey = ();
// 私钥
let privateKey = ();
公钥加密
const sm2 = require('sm-crypto').sm2;
(data, publicKey);
私钥解密
const sm2 = require('sm-crypto').sm2;
(data, privateKey);
工具类封装
import ;
import ;
import ;
import ;
import .SM2;
import .SM2Engine;
import ;
import ;
import ;
/**
* @author 猴哥
*/
public class Sm2Util {
/**
* 生成秘钥对
*
* @return 公钥和私钥
*/
public static Map<String, String> generator() {
SM2 sm2 = SmUtil.sm2();
String publicKey = (((BCECPublicKey) ()).getQ().getEncoded(false)).toUpperCase();
String privateKey = ((())).toUpperCase();
return new HashMap<String, String>(2) {{
put("publicKey", publicKey);
put("privateKey", privateKey);
}};
}
/**
* 加密
*
* @param publicKey 公钥
* @param data 明文
* @return 密文
*/
public static String encrypt(String publicKey, String data) {
return SmUtil.sm2(null, publicKey)
// 不写默认就是C1C3C2
.setMode(.C1C3C2)
.encryptHex((), )
// 加密后,密文前面会有04,需要去掉
.substring(2);
}
/**
* 解密
*
* @param privateKey 私钥
* @param data 密文
* @return 明文
*/
public static String decrypt(String privateKey, String data) {
// 确定前端不会加04,所以后端直接加(上面处理方式可能造成报错(Invalid point coordinates):原因前端加密后密文自带04开头)
data = "04" + data;
return SmUtil.sm2(privateKey, null)
// 不写默认就是C1C3C2
.setMode(.C1C3C2)
.decryptStr(data, );
}
}
国密sm3
添加依赖
<dependency>
<groupId></groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
工具类
import ;
import .Base64;
/**
* Sm3加密工具类
*
* @author 猴哥
*/
public class Sm3Util {
/**
* 加密
*
* @param key 秘钥
* @param data 明文
* @return 密文
*/
public static String encrypt(String key, String data) {
byte[] bytes = SmUtil.hmacSm3(().decode(key))
.digest(data);
return ().encodeToString(bytes);
}
}
国密sm4
添加依赖
<dependency>
<groupId></groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.27</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
加解密工具类
import ;
/**
* 国密sm4工具类
*
* @author 猴哥
*/
public class Sm4Util {
/**
* 加密
*
* @param key 秘钥
* @param data 明文
* @return 密文
*/
public static String encrypt(String key, String data) {
SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", ());
return (data).toUpperCase();
}
/**
* 解密
*
* @param key 秘钥
* @param data 密文
* @return 明文
*/
public static String decrypt(String key, String data) {
SymmetricCrypto sm4 = new SymmetricCrypto("SM4/ECB/PKCS5Padding", ());
return (data);
}
}
注意:加解密的key的长度要是16个字符,否则会失败