function sm2EncryptPwd(data) {
var publicKey = '04XXXXXXXXXXXXXXXXXXXXXXXXXXXCB42F6044B1BA8640B42AE038252F3490F02029E37B91D6E0796DE0B3D67166CDD971E556EF1D6B54ED350031817DED6B0C40';
return sm2Encrypt(data, publicKey, 1);
}
公钥用后端的生成公私钥对方法生成,请勿使用文章提到的公私钥对。
例如login.js使用了加密,即
login.js,调用加密函数
var encryptedPwd = sm2EncryptPwd(pwd);
3.后端Java解密
引用依赖库 bcprov-jdk15on-1.68.jar
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
login.java
私钥附上对应的值
pwd = new String(SM2Utils.decrypt(pwd, sm2PrivKey));
Sm2Utils.java
package com.sgsg.basic.encrypt.util;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.ECGenParameterSpec;
import java.util.Base64;
/**
* SM2工具类
* @author van
*/
public class SM2Utils {
/**
* 生成 SM2 公私钥对
*
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidAlgorithmParameterException
*/
public static KeyPair geneSM2KeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
// 获取一个椭圆曲线类型的密钥对生成器
final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
// 产生随机数
SecureRandom secureRandom = new SecureRandom();
// 使用SM2参数初始化生成器
kpg.initialize(sm2Spec, secureRandom);
// 获取密钥对
KeyPair keyPair = kpg.generateKeyPair();
return keyPair;
}
/**
* 生产hex秘钥对
*/
public static void geneSM2HexKeyPair(){
try {
KeyPair keyPair = geneSM2KeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
System.out.println("======== EC X Y keyPair ========");
System.out.println(privateKey);
System.out.println(publicKey);
System.out.println("======== hex keyPair ========");
System.out.println("hex priKey: " + getPriKeyHexString(privateKey));
System.out.println("hex pubKey: " + getPubKeyHexString(publicKey));
System.out.println("======== base64 keyPair ========");
System.out.println("base64 priKey: " + new String(Base64.getEncoder().encode(privateKey.getEncoded())));
System.out.println("base64 pubKey: " + new String(Base64.getEncoder().encode(publicKey.getEncoded())));
System.out.println("======== generate finished ========");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取私钥(16进制字符串,头部不带00长度共64)
*
* @param privateKey 私钥PrivateKey型
* @return
*/
public static String getPriKeyHexString(PrivateKey privateKey) {
// OK
// BCECPrivateKey s=(BCECPrivateKey)privateKey;
// String priKeyHexString = Hex.toHexString(s.getD().toByteArray());
// if(null!= priKeyHexString && priKeyHexString.length()==66 && "00".equals(priKeyHexString.substring(0,2))){
// return priKeyHexString.substring(2);
// }
// OK
BCECPrivateKey key = (BCECPrivateKey) privateKey;
BigInteger intPrivateKey = key.getD();
String priKeyHexString = intPrivateKey.toString(16);
return priKeyHexString;
}
/**
* 获取私钥 base64字符串
*
* @param privateKey 私钥PrivateKey型
* @return
*/
public static String getPriKeyBase64String(PrivateKey privateKey) {
return new String(Base64.getEncoder().encode(privateKey.getEncoded()));
}
/**
* 获取公钥(16进制字符串,头部带04长度共130)
*
* @param publicKey 公钥PublicKey型
* @return
*/
public static String getPubKeyHexString(PublicKey publicKey) {
BCECPublicKey key = (BCECPublicKey) publicKey;
return Hex.toHexString(key.getQ().getEncoded(false));
}
/**
* 获取公钥 base64字符串
*
* @param publicKey 公钥PublicKey型
* @return
*/
public static String getPubKeyBase64String(PublicKey publicKey) {
return new String(Base64.getEncoder().encode(publicKey.getEncoded()));
}
/**
* SM2加密算法
*
* @param publicKey 公钥
* @param data 明文数据
* @return
*/
public static String encrypt(String data, PublicKey publicKey) {
return encrypt(data.getBytes(StandardCharsets.UTF_8), publicKey);
}
/**
* @param data
* @param publicKey
* @return
* @author
* @version 1.0
* 2023年4月12日下午4:41:24
*/
public static String encrypt(byte[] data, PublicKey publicKey) {
BCECPublicKey key = (BCECPublicKey) publicKey;
return encrypt(data, Hex.toHexString(key.getQ().getEncoded(false)));
}
/**
* @param data
* @param pubKeyHexString
* @return
* @author
* @version 1.0
* 2023年4月12日下午4:46:37
*/
public static String encrypt(String data, String pubKeyHexString) {
return encrypt(data.getBytes(StandardCharsets.UTF_8), pubKeyHexString);
}
/**
* SM2加密算法
*
* @param pubKeyHexString 公钥(16进制字符串)
* @param data 明文数据
* @return hex字符串
*/
public static String encrypt(byte[] data, String pubKeyHexString) {
// 获取一条SM2曲线参数
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
// 构造ECC算法参数,曲线方程、椭圆曲线G点、大整数N
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
//提取公钥点
ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(pubKeyHexString));
// 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
// 设置sm2为加密模式
sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));
byte[] arrayOfBytes = null;
try {
arrayOfBytes = sm2Engine.processBlock(data, 0, data.length);
} catch (Exception e) {
System.out.println("SM2加密时出现异常:" + e.getMessage());
}
return Hex.toHexString(arrayOfBytes);
}
/**
* SM2解密算法
* @param cipherData hex格式密文
* @param privateKey 密钥PrivateKey型
* @return 明文
*/
public static String decrypt(String cipherData, PrivateKey privateKey) {
return decrypt(Hex.decode(cipherData), privateKey);
}
/**
* @param cipherData
* @param privateKey
* @return
* @author
* @version 1.0
* 2023年4月12日下午4:46:50
*/
public static String decrypt(byte[] cipherData, PrivateKey privateKey) {
BCECPrivateKey key = (BCECPrivateKey) privateKey;
return decrypt(cipherData, Hex.toHexString(key.getD().toByteArray()));
}
/**
* @param cipherData
* @param priKeyHexString
* @return
* @author
* @version 1.0
* 2023年4月12日下午4:46:53
*/
public static String decrypt(String cipherData, String priKeyHexString) {
// 使用BC库加解密时密文以04开头,传入的密文前面没有04则补上
if (!cipherData.startsWith("04")) {
cipherData = "04" + cipherData;
}
return decrypt(Hex.decode(cipherData), priKeyHexString);
}
/**
* SM2解密算法
*
* @param cipherData 密文数据
* @param priKeyHexString 私钥(16进制字符串)
* @return
*/
public static String decrypt(byte[] cipherData, String priKeyHexString) {
//获取一条SM2曲线参数
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
//构造domain参数
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
BigInteger privateKeyD = new BigInteger(priKeyHexString, 16);
ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
// 设置sm2为解密模式
sm2Engine.init(false, privateKeyParameters);
String result = "";
try {
byte[] arrayOfBytes = sm2Engine.processBlock(cipherData, 0, cipherData.length);
return new String(arrayOfBytes);
} catch (Exception e) {
System.out.println("SM2解密时出现异常:" + e.getMessage());
}
return result;
}
## 最后
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/43c5025690e64ac75910e8517f216b75.png)
![img](https://img-blog.csdnimg.cn/img_convert/cb67d9f753581ea2922cd0226b85edce.png)
![img](https://img-blog.csdnimg.cn/img_convert/2605fcf3a32350d25accfe80c5adf29d.png)
![img](https://img-blog.csdnimg.cn/img_convert/841a422815e9946a4177a2890b6eb6f8.png)
![img](https://img-blog.csdnimg.cn/img_convert/29a343772fe182dc182f2f29bb26af4e.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)
**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
wb9djVt-1715501591175)]
[外链图片转存中...(img-LufLJALY-1715501591175)]
[外链图片转存中...(img-ODXdcofs-1715501591175)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)
**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**