登录时用户名密码加密传输(包含前后端代码)

页面输入用户名密码登录过程中,如果没有对用户名密码进行加密处理,可能会导致传输过程中数据被窃取,就算使用https协议,在浏览器控制台的Request Payload中也是能直接看到传输的明文,安全感是否还是不足。

大致流程:前端,在请求登录接口之前对用户名密码进行加密,服务端收到请求后解密得到明文的用户名密码。

这里使用RSA非对称加密,前端使用公钥加密,后端使用私钥解密,这样就不会暴露私钥。

一、后端


1、pom文件添加依赖

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.8.22</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-crypto</artifactId>
            <version>5.8.22</version>
        </dependency>

2、加密解密工具类

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;


public class SecretConstant {

    /**
     * 登陆相关
     */
    public class LoginSecret{
        /**
         * 非对称加密 私钥 公钥私钥可以自己用代码生成,也可以在线生成,例如:https://tool.ip138.com/rsa/
         */
        public static final String PRIVATE_KEY = "MIIBOAIBAAJAflJQPKoKO9gz9Op2XINkHXVIyonzt/HClZRVf+2MyF4OLGckiBLM\n" +
                "rLq6jN/U4JlgIxCIni3zOsJdhIIF1D6fQwIDAQABAkAsKpeHPmSpm+Q+o6OSoRXl\n" +
                "/tXeivE9xTelmOF0AxiQDWRu1XWKAmjR2kKBgN/B9NlhBjW5+p4PW30UI7uCyKUR\n" +
                "AiEAw8ba06ZG7CZyXZVD8MhFx0ztg0kIE+ZLOqGpjSpKC70CIQClLfTWxpTbF4gb\n" +
                "lxDOJL5G1XiXcM516MUz6q3udTiG/wIgZ0v929yI4ULr5urB/UJ+Zsj1LOcUxwMk\n" +
                "wFvaDSy6AvUCIAehu/JAcpg82hkMPcaIhBIZwtycZa2k95eSfD7MQ7RZAiA+Y8yI\n" +
                "MkG4asXqoh2jryn40ih2q/GnXoCwdPXUa9E4MA==";

        /**
         * 非对称加密 公钥
         */
        public static final String PUBLIC_KEY = "MFswDQYJKoZIhvcNAQEBBQADSgAwRwJAflJQPKoKO9gz9Op2XINkHXVIyonzt/HClZRVf+2MyF4OLGckiBLMrLq6jN/U4JlgIxCIni3zOsJdhIIF1D6fQwIDAQAB";

    }

    /**
     * 测试一下
     * @param args
     */
    public static void main(String[] args) {
        String un = "admin";
        String pw = "admin@123456";
        // 用户名密码解密
        RSA rsa = new RSA(SecretConstant.LoginSecret.PRIVATE_KEY, SecretConstant.LoginSecret.PUBLIC_KEY);
        String un_jm = rsa.encryptBase64(un,KeyType.PublicKey);
        System.out.println("公钥加密后:"+un_jm);
        // 前端传过来的用户名密码是通过公钥加密的
        String userName_plaintext = rsa.decryptStr(un_jm, KeyType.PrivateKey);
        System.out.println("私钥解密后:"+userName_plaintext);
        // 加密后的密文
        String temp = "djCaCjhwVRc29vNHEIUqoGkn0azDjGdjHHV+zetw8GcKmJ8u2/VgAX54G/zzpcrBrpkR+SmS7QPkpSz5s05OLA==";
        System.out.println("私钥解密后:"+rsa.decryptStr(temp, KeyType.PrivateKey));

    }
}

3、使用示例

    public BaseResult login(String userNameCipher, String passwordCipher) {
        // 用户名密码解密
        RSA rsa = new RSA(SecretConstant.LoginSecret.PRIVATE_KEY, SecretConstant.LoginSecret.PUBLIC_KEY);
        String userName = rsa.decryptStr(userNameCipher, KeyType.PrivateKey);
        String password = rsa.decryptStr(passwordCipher, KeyType.PrivateKey);
        // 登录逻辑...
    }


二、前端


前端使用公钥加密,秘钥可以直接写在js文件中,因为用的是公钥所以不怕泄漏,当然了,如果想灵活一点,可以把公钥放在后端,前端通过接口查询得到公钥。

1、加密工具类

文件名称encryptUtils.js,内容如下,其他地方调用即可。


import JSEncrypt from 'jsencrypt';

// 可能需要需要先安装jsencrypt库,执行:npm install jsencrypt 

/**
 * 登录使用的公钥,
 * 如果想灵活一点,可以把公钥放在后端,前端通过接口查询得到公钥。
 * @type {string}
 */
const LOGIN_PUBLIC_KEY = "MFswDQYJKoZIhvcNAQEBBQADSgAwRwJAflJQPKoKO9gz9Op2XINkHXVIyonzt/HClZRVf+2MyF4OLGckiBLMrLq6jN/U4JlgIxCIni3zOsJdhIIF1D6fQwIDAQAB";



/**
 * 获取登录使用的公钥
 * @returns {string}
 */
export const getLoginPublicKey = () => {
  return LOGIN_PUBLIC_KEY;
}


/**
 * 加密
 * @param text  需要加密的文本
 * @param publicKey   公钥
 * @returns {string | false}
 */
export const encodeStr = (text, publicKey) => {
  // RSA(非对称加密)
  const JSE = new JSEncrypt();
  // 设置公钥
  JSE.setPublicKey(publicKey);
  return JSE.encrypt(text);
}

2、使用示例

在需要加密的地方调用上面的方法

import request from '@/utils/request';
import { getLoginPublicKey, encodeStr } from '@/utils/encryptUtils';

/**
 * 请求后端登录的方法
 */
export async function login(params) {
  // 公钥加密
  params.userName = encodeStr(params.userName, getLoginPublicKey());
  params.password = encodeStr(params.password, getLoginPublicKey());
  const result = await request('/api/v1/user/login', {
    method: 'POST',
    type: 'JSON',
    body: params
  });
  return result;
}

前端加密后请求,后端解密得到明文。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值