ruoyi-前端明文传递-国密2加密-后端解密
一、前端代码
1、添加 /src/utils/sm2.js 文件
导入依赖:npm 安装 sm-crypto npm i sm-crypto
import { sm2 } from 'sm-crypto' /** * SM2加密 用于密码传输 * @param {string} publicKey 后端返回公钥 04开头 * @param {string} plainText 明文密码 * @returns {string} 加密后hex密文 C1C3C2 * * mode = 0 → 输出 C1C2C3 (旧模式) * mode = 1 → 输出 C1C3C2 (标准模式,推荐,Hutool 默认支持) * > SM2 密文三部分: * * - C1:椭圆曲线点(公钥随机点) * - C2:密文本体 * - C3:SM3 校验摘要 */ export function sm2EncryptPassword(plainText) { if (!plainText) return '' // sm-crypto默认输出C1C3C2,和后端BC库保持一致 const publicKey = "999999"; const cipher = sm2.doEncrypt(plainText, publicKey, 1) // 注意后台解析 需要 有 “04” return "04"+cipher; }2、找到 /src/store/modules/ 目录下 user.js 文件,修改Login方法传输格式。
修改如下:把 const password = userInfo.password 注释掉。
import { sm2EncryptPassword } from '@/utils/sm2' Login({ commit }, userInfo) { const username = userInfo.username.trim() // const password = userInfo.password // 新增如下 代码 进行加密 const password = sm2EncryptPassword(userInfo.password) const code = userInfo.code const uuid = userInfo.uuid return new Promise((resolve, reject) => { login(username, password, code, uuid).then(res => { setToken(res.token) commit('SET_TOKEN', res.token) resolve() }).catch(error => { reject(error) }) }) },
二、后端代码
1、在common模块中的 pom.xml 文件中添加如下内容:
<!--国密BC库 JDK8兼容--> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.68</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.22</version> </dependency>2、在commone模块中添加 工具类 Sm2Util.java
package com.ruoyi.common.utils; import cn.hutool.core.util.HexUtil; import cn.hutool.crypto.BCUtil; import cn.hutool.crypto.SecureUtil; 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 org.apache.commons.lang3.StringUtils; import java.security.KeyPair; public class Sm2Util { public static KeyPair generateKeyPair() { return SecureUtil.generateKeyPair("SM2"); } public static String publicKey = "公钥"; public static String privateKey = "密钥"; public static String encrypt(String str) { try { SM2 sm2 = new SM2(privateKey, publicKey); sm2.setMode(SM2Engine.Mode.C1C3C2); return sm2.encryptHex(str, KeyType.PublicKey); } catch (Exception e) { throw new RuntimeException("sm2加密失败" + e); } } public static String decrypt(String str) { try { // 前端传过来的 加密串必须 开头必须有 04 SM2 sm2 = new SM2(privateKey, publicKey); sm2.setMode(SM2Engine.Mode.C1C3C2); return sm2.decryptStr(str, KeyType.PrivateKey); } catch (Exception e) { throw new RuntimeException("sm2解密失败" + e); } } public static void main(String[] args) { Sm2Util sm2Util = new Sm2Util(); // 生成密钥对 KeyPair keyPair = sm2Util.generateKeyPair(); // 服务器端使用 【后台使用】 // 生成私钥 byte[] prikey= keyPair.getPrivate().getEncoded(); String privateKey = HexUtil.encodeHexStr(prikey); // 生成公钥 byte[] pubkey=keyPair.getPublic().getEncoded(); String publicKey = HexUtil.encodeHexStr(pubkey); System.out.println("privateKey=>" + privateKey); System.out.println("publicKey=>" + publicKey); // 前端使用 【js文件使用使用】 // 生成公钥 Q,以Q值做为js端的加密公钥 BCECPublicKey bce= (BCECPublicKey) keyPair.getPublic(); byte[] bceQ= bce.getQ().getEncoded(false); String publicKeyQ = HexUtil.encodeHexStr(bceQ); System.out.println("公钥Q:"+ publicKeyQ); // 生成私钥 D,以D值做为js端的解密私钥 byte[] encQ=BCUtil.encodeECPrivateKey(keyPair.getPrivate()); String privateKeyD = HexUtil.encodeHexStr(encQ); System.out.println("私钥D:"+ privateKeyD); } }3、修改登录校验方法 SysLoginService 下的 login 方法,具体代码如下:
public String login(String username, String password, String code, String uuid){ //解密 方法 获取前端 传值 password = Sm2Util.decrypt(password); // 验证码校验 validateCaptcha(username, code, uuid); // 登录前置校验 loginPreCheck(username, password); // 用户验证 Authentication authentication = null; ........ }
注意:前端在向 后端传值时 记得在开头 添加 04【如果使用原生 不用Hutool 就不用加了】