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

页面输入用户名密码登录过程中,如果没有对用户名密码进行加密处理,可能会导致传输过程中数据被窃取,就算使用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;
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/896601.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

redis—cluster集群

一&#xff1a;Redis Cluster特点 多主多从&#xff0c;去中心化&#xff1a;从节点作为备用&#xff0c;复制主节点&#xff0c;不做读写操作&#xff0c;不提供服务不支持处理多个key&#xff1a;因为数据分散在多个节点&#xff0c;在数据量大高并发的情况下会影响性能&…

Columns Page “列”页面

“列”页提供了列管理工具&#xff0c;其中包括用于添加和删除列的按钮、显示绑定数据源中字段名称的列表框以及网格列、提供对所选列属性的访问的属性网格。 Columns 页面提供 Column properties &#xff08;列属性&#xff09;、Column options &#xff08;列选项&#xff…

Electron-(三)网页报错处理与请求监听

在前端开发中&#xff0c;Electron 是一个强大的框架&#xff0c;它允许我们使用 Web 技术构建跨平台的桌面应用程序。在开发过程中&#xff0c;及时处理网页报错和监听请求是非常重要的环节。本文将详细介绍 Electron 中网页报错的日志记录、webContents 的监听事件以及如何监…

如何使用JMeter进行性能测试的保姆级教程

性能测试是确保网站在用户访问高峰时保持稳定和快速响应的关键环节。作为初学者&#xff0c;选择合适的工具尤为重要。JMeter 是一个强大的开源性能测试工具&#xff0c;可以帮助我们轻松模拟多用户场景&#xff0c;测试网站的稳定性与性能。本教程将引导你通过一个简单的登录场…

微信小程序canvas 生成二维码图片,画图片,生成图片,将两个canvas结合并保存图片

需求实现步骤如下 先定义两个canvas一个canvas myQrcode画二维码的图片另一个canvas mycanvas画一个背景图&#xff0c;并把二维码画到这个canvas上&#xff0c;mycanvas这个canvas生成一张图片&#xff0c;返回图片的临时路径最后保存图片到手机 首先wxml,新版微信小程序can…

Java之继承抽象类用法实例(三十一)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

使用Matplotlib绘制箱线图:详细指南与示例

在数据分析和可视化领域&#xff0c;箱线图&#xff08;Box Plot&#xff09;是一种强大的工具&#xff0c;用于展示数据的分布特征&#xff0c;包括中位数、四分位数、异常值等。本文将详细介绍如何使用Matplotlib库在Python中绘制箱线图&#xff0c;并通过一个实际的血压数据…

从0开始linux(13)——进程(4)进程空间地址(1)

欢迎来到博主的专栏&#xff1a;从0开始linux 博主ID&#xff1a;代码小豪 文章目录 进程空间地址 还记得博主在之前介绍子进程时说过的话吗&#xff1f;子进程与父进程共享代码&#xff0c;而数据却不共享&#xff1b;这很好理解&#xff0c;因为子进程和父进程是不同的进程&a…

Java线程安全集合之COW

概述 java.util.concurrent.CopyOnWriteArrayList写时复制顺序表&#xff0c;一种采用写时复制技术&#xff08;COW&#xff09;实现的线程安全的顺序表&#xff0c;可代替java.util.ArrayList用于并发环境中。写时复制&#xff0c;在写入时&#xff0c;会复制顺序表的新副本&…

K8S调度不平衡问题分析过程和解决方案

不平衡问题排查 问题描述&#xff1a; 1、业务部署大量pod(据反馈&#xff0c;基本为任务型进程)过程中&#xff0c;k8s node内存使用率表现不均衡&#xff0c;范围从80%到百分之几&#xff1b; 2、单个node内存使用率超过95%&#xff0c;仍未发生pod驱逐&#xff0c;存在node…

Janus:开创统一的多模态理解和生成框架

Janus是DeepSeek开源的多模式自回归框架&#xff0c;统一了多模态理解和生成&#xff0c;既可以理解图片内容又可以生成图片。 1.简介 Janus 是一种新颖的自回归框架&#xff0c;它将多模态理解和生成统一起来。它通过将视觉编码解耦为单独的路径来解决以前方法的局限性&…

jmeter发送post请求

在jmeter中&#xff0c;有两种常用的请求方式&#xff0c;get和post.它们两者的区别在于get请求的参数一般是放在路径中&#xff0c;可以使用用户自定义变量和函数助手等方式进行参数化&#xff0c;而post请求的参数不能随url发送&#xff0c;而是作为请求体提交给服务器。而在…

OpenWRT 和 Padavan 路由器配置网络打印机 实现远程打印

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 之前有给大家介绍过 Armbian 安装 CUPS 作为打印服务器&#xff0c;像是 N1 盒子、玩客云&#xff0c;甚至是随身 WiFi 都可以通过 CUPS 来进行打印。但是有些朋友不想专门为打印机添置一个设备&#xff0…

Spring AI 1.0.0 M1版本新特性!

Spring AI 1.0.0 M1版本新特性介绍 前言一、在1.0.0 M1版本中&#xff0c;主要有以下新特性&#xff1a;1.ChatModel2.ChatClient3.多模态的支持4.模型评估RequestResponseAdvisor接口MessageChatMemoryAdvisorPromptChatMemoryAdvisorQuestionAnswerAdvisor动态过滤表达式 Vec…

爬虫逆向-js进阶(续写,搭建网站)

1.搭建简单网站1 from flask import Flask,render_template import requests import json app Flask(name)# **location**的温度是**temp**度&#xff0c;天气状况&#xff1a;**desc**app.route(/) # 绑定处理函数 def index_url():location 101010100data get_weather(lo…

黑马JavaWeb-day02

什么是JavaScript&#xff1f; JavaScript&#xff1a;简称Js,是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互 JavaScript和Java是完全不同的语言&#xff0c;无论是概念还是设计。但是基础语法类似。 JavaScript JavaScript引入方式…

第三方软件测试中心有什么特点?江苏软件测试中心推荐

随着软件市场的激烈竞争&#xff0c;软件企业越来越多&#xff0c;为了更好的服务用户以及专心于产品开发工作&#xff0c;将软件测试外包给第三方软件测试中心已经成为了行业发展趋势。第三方软件测试中心顾名思义就是区别于软件开发方和需求方的第三方存在&#xff0c;是专门…

使用 MongoDB 构建 AI:利用实时客户数据优化产品生命周期

在《使用 MongoDB 构建 AI》系列博文中&#xff0c;我们看到越来越多的企业正在利用 AI 技术优化产品研发和用户支持流程。例如&#xff0c;我们介绍了以下案例&#xff1a; Ventecon 的 AI 助手帮助产品经理生成和优化新产品规范 Cognigy 的对话式 AI 帮助企业使用任意语言&a…

《MYSQL实战45讲 》 优化器如何选择索引?

SHOW VARIABLES LIKE long_query_time; set long_query_time0 优化器如何选择索引&#xff1f; 1.扫描的行数 估计出各个索引大致的要扫描的行数&#xff0c;行数越少&#xff0c;效率越高。 索引的基数也叫区分度&#xff0c;就是这个索引所在的字段上不同的值又多少个。优…

10.21 多进程间通信-信号、消息队列

作业&#xff1a;使用消息队列实现两个进程间通信 编程代码&#xff1a;使用父子进程实现通信 msgsnd.c #include <myhead.h> //定义自定义函数用于接收僵尸进程 void handler(int signo){if(signoSIGCHLD){while(waitpid(-1,NULL,WNOHANG)>0);} } //定义存储消息队…