java/vue使用国密sm2、sm3、sm4进行数据加密

时间:2024-11-13 19:41:44

简介(必看)

国密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个字符,否则会失败