开发喵星球

RuoYi-App 集成 JSEncrypt 实现密码加密传输(360)

RuoYi-App 中,登录接口的密码默认是明文传输的。如果对数据传输的安全性有要求,可以通过集成 JSEncrypt 实现密码的加密传输。以下是实现的具体步骤:

1. 引入 JSEncrypt 前端库

首先,在 utils 目录下新增 jsencrypt.min.js 文件,这是前端的加密插件库。

你可以从以下链接下载 jsencrypt.min.js 文件:

下载链接:https://pan.baidu.com/s/1nN9Wdvy1Y0NEx8pxtrHrHg?pwd=meow
提取码:meow

下载后,将 jsencrypt.min.js 文件放入 utils 目录。

2. 编写加密工具函数

utils 目录中再新增一个 jsencrypt.js 文件,用于封装加密和解密的逻辑。

import JSEncrypt from '@/utils/jsencrypt.min'

// 设置公钥和私钥,密钥对可以通过在线工具生成,例如:http://web.chacuo.net/netrsakeypair
const publicKey = `MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJSAx+2dGvJ4LEFVbXQEpsJxEEDyb76l
tMa+7cUqUS0FiduJFtD7dZCXENOW+aU6UAVridGNQaT1f3ht2G/hAvMCAwEAAQ==`

const privateKey = `MIIBOgIBAAJBAJSAx+2dGvJ4LEFVbXQEpsJxEEDyb76ltMa+7cUqUS0FiduJFtD7
dZCXENOW+aU6UAVridGNQaT1f3ht2G/hAvMCAwEAAQJANlZY0UznC0mFh/JmNklt
a0BLnjgXQz8GwqIiBj7RrRMF96dhXBkrC+RaWUx9PvQguahaqhm1zfJTF22WA42B
YQIhANxl7ZN0xvi3nfwcs5r4upIpa0INnRTmk2rEx1dkV/+PAiEArH3KuyKHrkkS
orl2c7B0pHmlcv8el9g3c/OnYqvuFF0CIBJphX5zHAg9NrqQH0UMEHITeb1r67qK
RLh/tfOME3nrAiBQAwnHRH0rmznJwb3wbCmvIb5dWXoXdXRDlQJQAvCtAQIhAIN+
om2+VWY39zR+XVJKeeWJsFRlsPPsn0RFG6iZuF+X`

// 加密函数
export function encrypt(text) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey) // 设置公钥
  return encryptor.encrypt(text) // 加密数据
}

// 解密函数
export function decrypt(text) {
  const encryptor = new JSEncrypt()
  encryptor.setPrivateKey(privateKey) // 设置私钥
  return encryptor.decrypt(text) // 解密数据
}

上述代码中,我们使用了 RSA 公钥和私钥。你可以使用在线工具生成密钥对,将其替换成自己的密钥。

3. 修改登录逻辑实现密码加密

接下来,我们在登录逻辑中应用 RSA 加密。在 login.js 文件中,将用户输入的密码进行加密后再发送到服务器。

import { encrypt } from '@/utils/jsencrypt'

export function login(username, password, code, uuid) {
  // 使用 JSEncrypt 对密码进行加密
  password = encrypt(password);

  // 继续原有的登录逻辑
  .........
}

通过在登录请求中加密密码,能够避免密码以明文方式传输,提升了数据的安全性。

4. 服务器端实现 RSA 解密

在服务器端的 Java 部分,我们需要实现对前端加密数据的解密。在工具类包下新增 RsaUtils.java 文件,用于封装 RSA 加密和解密的功能。

package com.ruoyi.common.utils.sign;

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA加密解密
 * 
 * @author ruoyi
 **/
public class RsaUtils
{
    // Rsa 私钥
    public static String privateKey = "MIIBOgIBAAJBAJSAx+2dGvJ4LEFVbXQEpsJxEEDyb76ltMa+7cUqUS0FiduJFtD7"
+ "dZCXENOW+aU6UAVridGNQaT1f3ht2G/hAvMCAwEAAQJANlZY0UznC0mFh/JmNklt"
+ "a0BLnjgXQz8GwqIiBj7RrRMF96dhXBkrC+RaWUx9PvQguahaqhm1zfJTF22WA42B"
+ "YQIhANxl7ZN0xvi3nfwcs5r4upIpa0INnRTmk2rEx1dkV/+PAiEArH3KuyKHrkkS"
+ "orl2c7B0pHmlcv8el9g3c/OnYqvuFF0CIBJphX5zHAg9NrqQH0UMEHITeb1r67qK"
+ "RLh/tfOME3nrAiBQAwnHRH0rmznJwb3wbCmvIb5dWXoXdXRDlQJQAvCtAQIhAIN+"
+ "om2+VWY39zR+XVJKeeWJsFRlsPPsn0RFG6iZuF+X";

    /**
     * 私钥解密
     *
     * @param privateKeyString 私钥
     * @param text 待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String text) throws Exception
    {
        return decryptByPrivateKey(privateKey, text);
    }

    /**
     * 公钥解密
     *
     * @param publicKeyString 公钥
     * @param text 待解密的信息
     * @return 解密后的文本
     */
    public static String decryptByPublicKey(String publicKeyString, String text) throws Exception
    {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 私钥加密
     *
     * @param privateKeyString 私钥
     * @param text 待加密的信息
     * @return 加密后的文本
     */
    public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception
    {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 私钥解密
     *
     * @param privateKeyString 私钥
     * @param text 待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception
    {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 公钥加密
     *
     * @param publicKeyString 公钥
     * @param text 待加密的文本
     * @return 加密后的文本
     */
    public static String encryptByPublicKey(String publicKeyString, String text) throws Exception
    {
        X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 构建RSA密钥对
     *
     * @return 生成后的公私钥信息
     */
    public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException
    {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        return new RsaKeyPair(publicKeyString, privateKeyString);
    }

    /**
     * RSA密钥对对象
     */
    public static class RsaKeyPair
    {
        private final String publicKey;
        private final String privateKey;

        public RsaKeyPair(String publicKey, String privateKey)
        {
            this.publicKey = publicKey;
            this.privateKey = privateKey;
        }

        public String getPublicKey()
        {
            return publicKey;
        }

        public String getPrivateKey()
        {
            return privateKey;
        }
    }
}

5. 修改登录服务中的解密逻辑

接下来,我们修改 SysLoginService.java 文件,将登录请求中的密码进行解密处理:

// 对接收到的密码进行解密
String decryptedPassword = RsaUtils.decryptByPrivateKey(password);

// 使用解密后的密码继续登录处理逻辑
UsernamePasswordAuthenticationToken authenticationToken = 
    new UsernamePasswordAuthenticationToken(username, decryptedPassword);

authentication = authenticationManager.authenticate(authenticationToken);

在这里,我们使用 RsaUtils 工具类对加密的密码进行解密,然后通过解密后的密码进行身份验证。

6. 测试登录功能

最后,启动项目,访问 http://localhost:9090/login 登录页面,测试加密后的密码是否能够正常传输。在提交登录请求时,检查密码在请求体中的加密情况,并确保服务器端能够成功解密密码并进行验证。

通过上述步骤,你将成功在 RuoYi-App 中集成 JSEncrypt,实现了前端密码加密传输,并在服务器端实现了解密处理,从而提升了系统的安全性。

小结

通过使用 RSA 非对称加密技术,前端的敏感信息在传输过程中得到了加密保护,减少了被拦截或泄露的风险。同时,服务器端的解密逻辑保证了用户正常的登录操作。

   
分类:Java/OOP 作者:无限繁荣, 吴蓉 发表于:2024-10-14 15:35:02 阅读量:84
<<   >>


powered by kaifamiao