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

java端

添加依赖



	org.bouncycastle
	bcprov-jdk15to18
	1.72


	org.bouncycastle
	bcprov-jdk15on
	1.70



	cn.hutool
	hutool-all
	5.8.9

生成公钥和私钥

SM2 sm2 = SmUtil.sm2();
String privateKey = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm2.getPrivateKey()));
String publicKey = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false));

公钥加密

/**
 * 加密
 *
 * @param publicKey 公钥
 * @param data 明文
 * @return 密文
 */
public static String encrypt(String publicKey, String data) {
	return SmUtil.sm2(null, publicKey)
			.encryptHex(data.getBytes(), KeyType.PublicKey)
			// 加密后,密文前面会有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, KeyType.PrivateKey);
}

vue端

添加依赖

npm install sm-crypto --save

生成公钥和私钥

const sm2 = require('sm-crypto').sm2

let keypair = sm2.generateKeyPairHex();
// 公钥
let publicKey = keypair.publicKey.toUpperCase();
// 私钥
let privateKey = keypair.privateKey.toUpperCase();

公钥加密

const sm2 = require('sm-crypto').sm2;
sm2.doEncrypt(data, publicKey);

私钥解密

const sm2 = require('sm-crypto').sm2;
sm2.doDecrypt(data, privateKey);

工具类封装

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.BCUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 猴哥
 */
public class Sm2Util {
	/**
	 * 生成秘钥对
	 *
	 * @return 公钥和私钥
	 */
	public static Map generator() {
		SM2 sm2 = SmUtil.sm2();
		String publicKey = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false)).toUpperCase();
		String privateKey = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm2.getPrivateKey())).toUpperCase();
		return new HashMap(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(SM2Engine.Mode.C1C3C2)
				.encryptHex(data.getBytes(), KeyType.PublicKey)
				// 加密后,密文前面会有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(SM2Engine.Mode.C1C3C2)
				.decryptStr(data, KeyType.PrivateKey);
	}
}

你可能感兴趣的:(Java,JavaScript,vue.js,java,前端)