rsa加密登录解决方案
1.问题
账密登录方式中用户输入密码后,把账号、密码通过http传输到后端进行校验,然而密码属于敏感信息,不能以明文传输,否则容易被拦截窃取,因此需要考虑如何安全传输密码
2.解决方案
使用rsa加密方式,rsa属于非对称加密,特点就是公钥加密私钥解密
2.1后端生成公钥私钥
生成公私钥,把公钥返回给前端,私钥用redis缓存
ManagerController.java
@GetMapping("/key")public ResponseEntity<ApiResponse> key(@RequestParam("loginNo") String loginNo) {String key = managerService.generateKey(loginNo);return ApiResponse.success(key);}
ManagerServiceImpl.java
@Overridepublic String generateKey(String loginNo) {QueryWrapper<Manager> wrapper = new QueryWrapper<>();wrapper.eq("loginNo", loginNo);Manager entity = this.getOne(wrapper);if (Objects.isNull(entity)) {throw new CodeException("用户不存在:loginNo=" + loginNo);}try {KeyPair keyPair = RSAUtil.generateKeyPair();String publicKey = RSAUtil.getPublicKey(keyPair);String privateKey = RSAUtil.getPrivateKey(keyPair);log.info("publicKey={}", publicKey);log.info("privateKey={}", privateKey);String redisKey = RedisKey.MANAGE_LOGIN_RSA_PRIVATEKEY + "$" + loginNo;// 清除缓存redisService.del(redisKey);// 私钥添加到缓存redisService.set(redisKey, privateKey, 5, TimeUnit.MINUTES);return publicKey;} catch (Exception e) {log.error("生成rsa密钥失败", e);}return null;}
RSAUtil.java
public class RSAUtil {private static final Charset CHARSET = StandardCharsets.UTF_8;private static final String ALGORITHM = "RSA";/*** 生成密钥对* @return* @throws NoSuchAlgorithmException*/public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);keyPairGenerator.initialize(1024);return keyPairGenerator.generateKeyPair();}/*** 生成公钥* @param keyPair* @return*/public static String getPublicKey(KeyPair keyPair) {PublicKey publicKey = keyPair.getPublic();byte[] bytes = base64Encode(publicKey.getEncoded());return new String(bytes, CHARSET);}/*** 生成私钥* @param keyPair* @return*/public static String getPrivateKey(KeyPair keyPair) {PrivateKey privateKey = keyPair.getPrivate();byte[] bytes = base64Encode(privateKey.getEncoded());return new String(bytes, CHARSET);}/*** base64加密* @param bytes* @return*/public static byte[] base64Encode(byte[] bytes) {return Base64.getEncoder().encode(bytes);}/*** base64解密* @param bytes* @return*/public static byte[] base64Decode(byte[] bytes) {return Base64.getDecoder().decode(bytes);}/*** base64解密* @param src* @return*/public static byte[] base64Decode(String src) {return Base64.getDecoder().decode(src);}/*** 解密* @param key* @param data* @return* @throws NoSuchAlgorithmException* @throws InvalidKeySpecException* @throws NoSuchPaddingException* @throws InvalidKeyException* @throws IllegalBlockSizeException* @throws BadPaddingException*/public static String decrypt(String key, String data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {byte[] bytes = base64Decode(key);PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.DECRYPT_MODE, privateKey);return new String(cipher.doFinal(base64Decode(data.getBytes(CHARSET))), CHARSET);}
2.2前端使用公钥加密
安装这个依赖
npm install jsencrypt@3.2.0
import JSEncrypt from 'jsencrypt';// key为后端返回的公钥,this.form.password为明文密码
const jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(key);
// pwd为加密后的密码
var pwd = jsEncrypt.encrypt(this.form.password);
2.3后端使用私钥解密
从redis获取私钥,用私钥解密,得到明文后和数据库保存的密码比对,数据库的密码是以用户id为盐值对明文密码作md5加密,相同则放行,否则报错,注意登录成功的话需要把redis的密钥移除
ManagerController.java
@PostMapping("/login")public ResponseEntity<ApiResponse> login(@RequestParam("loginNo") String loginNo, @RequestParam("password") String password)throws Exception {UserDTOWithToken dto = managerService.login(loginNo, password);return ApiResponse.success(dto);}
ManagerServiceImpl.java
@Overridepublic UserDTOWithToken login(String loginNo, String password) throws Exception {QueryWrapper<Manager> wrapper = new QueryWrapper<>();wrapper.eq("loginNo", loginNo);Manager entity = this.getOne(wrapper);if (Objects.isNull(entity)) {throw new CodeException("用户不存在:loginNo=" + loginNo);}String redisKey = RedisKey.MANAGE_LOGIN_RSA_PRIVATEKEY + "$" + loginNo;// 从缓存获取私钥String privateKey = (String) redisService.get(redisKey);if (StrUtil.isEmpty(privateKey)) {throw new CodeException("私钥不存在");}// 用私钥解密String realPassword = RSAUtil.decrypt(privateKey, password);log.info("realPassword={}", realPassword);// 校验密码Digester digester = new Digester(DigestAlgorithm.MD5);digester.setSalt(entity.getId().getBytes(StandardCharsets.UTF_8));String encodePassword = digester.digestHex(realPassword);log.info("encodePassword={}", encodePassword);if (!encodePassword.equals(entity.getPassword())) {throw new CodeException("密码错误");}//从认证服务获取tokenResponseEntity<ApiResponse> responseEntity = authClient.token(AuthConst.PASSWORD_GRANT_TYPE, AuthConst.ADMIN_CLIENT_ID,AuthConst.ADMIN_CLIENT_SECRET, null, loginNo, password);ApiResponse response = responseEntity.getBody();TokenDTO tokenDTO = response.toObject(TokenDTO.class);if (Objects.isNull(tokenDTO)) {throw new CodeException("获取token失败:" + response.getMessage());}UserDTOWithToken dto = new UserDTOWithToken();dto.setUserId(entity.getId());dto.setToken(tokenDTO);entity.setLoginTime(LocalDateTime.now());Integer loginCount = entity.getLoginCount();entity.setLoginCount(Objects.isNull(loginCount) ? 1 : loginCount + 1);entity.setUpdateTime(LocalDateTime.now());this.updateById(entity);// 成功则清除缓存的私钥redisService.del(redisKey);return dto;}
3.总结
非对称加密还有其它算法,rsa是其中一种
后端存储私钥除了redis也可以用其它缓存工具如J2Cache
相关文章:
rsa加密登录解决方案
1.问题 账密登录方式中用户输入密码后,把账号、密码通过http传输到后端进行校验,然而密码属于敏感信息,不能以明文传输,否则容易被拦截窃取,因此需要考虑如何安全传输密码 2.解决方案 使用rsa加密方式,r…...
速盾:海外服务器用了cdn还是卡怎么办
海外服务器使用CDN卡顿问题的解决办法 在如今互联网高速发展的时代,海外服务器成为了许多企业和个人用户的首选,因为它能够提供更高的带宽和更稳定的网络连接。然而,尽管海外服务器在网络性能方面表现出色,但在使用过程中仍然可能…...
[python-opencv] PNG 裁切物体
拿到一组图PNG的图,边缘有点太宽了,需要裁切一下,为了这个需求,简单复习一下基本语法。 1. 读取PNG的4个通道 image cv.imread(image_path, cv.IMREAD_UNCHANGED) 附参数说明: IMREAD_UNCHANGED -1 返…...
机器学习——有监督学习和无监督学习
有监督学习 简单来说,就是人教会计算机学会做一件事。 给算法一个数据集,其中数据集中包含了正确答案,根据这个数据集,可以对额外的数据希望得到一个正确判断(详见下面的例子) 回归问题 例如现在有一个…...
MySQL单主模式部署组复制集群
前言 本篇文章介绍MySQL8.0.27版本的组复制详细搭建过程,教你如何快速搭建一个三节点的单主模式组复制集群。 实际上,MySQL组复制是MySQL的一个插件 group_replication.so,组中的每个成员都需要配置并安装该插件,配置和安装过程…...
【大厂AI课学习笔记】【1.5 AI技术领域】(10)对话系统
对话系统,Dialogue System,也称为会话代理。是一种模拟人类与人交谈的计算机系统,旨在可以与人类形成连贯通顺的对话,通信方式主要有语音/文本/图片,当然也可以手势/触觉等其他方式 一般我们将对话系统,分…...
【ARM 嵌入式 编译系列 2.7 -- GCC 编译优化参数详细介绍】
请阅读【嵌入式开发学习必备专栏 】 文章目录 GCC 编译优化概述常用优化等级-O1 打开的优化选项-O2 打开的优化选项-O3 打开的优化选项-Os 打开的优化选项优化技术使用优化选项的注意事项GCC 编译优化概述 GCC(GNU Compiler Collection)包含了用于C、C++、Objective-C、Fort…...
《剑指 Offer》专项突破版 - 面试题 38、39 和 40 : 通过三道面试题详解单调栈(C++ 实现)
目录 面试题 38 : 每日温度 面试题 39 : 直方图最大矩形面积 方法一、暴力求解 方法二、递归求解 方法三、单调栈法 面试题 40 : 矩阵中的最大矩形 面试题 38 : 每日温度 题目: 输入一个数组,它的每个数字是某天的温度。请计算每天需要等几天才会…...
动态规划C语言
#include <stdio.h> #include <stdlib.h> //0-1背包问题是一种经典的组合优化问题, //问题描述为:有一个给定容量的背包和一组具有不同价值和重量的物品,如何选择物品放入背包中,以使得背包中物品的总价值最大化&…...
基于微信小程序的校园二手交易平台
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
K8S系列文章之 [使用 Alpine 搭建 k3s]
官方文档:K3s - 轻量级 Kubernetes | K3s 官方描述,可运行在 systemd 或者 openrc 环境上,那就往精简方向走,使用 alpine 做系统。与 RHEL、Debian 的区别,主要在防火墙侧;其他基础配置需求类似࿰…...
计算机视觉 | OpenCV 实现手势虚拟控制亮度和音量
Hi,大家好,我是半亩花海。在当今科技飞速发展的时代,我们身边充斥着各种智能设备,然而,如何更便捷地与这些设备进行交互却是一个不断被探索的课题。本文将主要介绍一个基于 OpenCV 的手势识别项目,通过手势…...
python28-Python的运算符之三目运算符
Python可通过if语句来实现三目运算符的功能,因此可以近似地把这种if语句当成三目运算符。作为三目运算符的f语句的语法格式如下 True_statements if expression else False_statements 三目运算符的规则是:先对逻辑表达式expression求值,如果逻辑表达式…...
高德 API 10009
问题 笔者使用高德地图所提供的API接口,访问接口报错 {"info":"USERKEY_PLAT_NOMATCH","infocode":"10009","status":"0","sec_code_debug":"d41d8cd98f00b204e9800998ecf8427e"…...
Go 语言中如何大小端字节序?int 转 byte 是如何进行的?
嗨,大家好!我是波罗学。 本文是系列文章 Go 技巧第十五篇,系列文章查看:Go 语言技巧。 我们先看这样一个问题:“Go 语言中,将 byte 转换为 int 时是否涉及字节序(endianness)&#x…...
论文阅读——MP-Former
MP-Former: Mask-Piloted Transformer for Image Segmentation https://arxiv.org/abs/2303.07336 mask2former问题是:相邻层得到的掩码不连续,差别很大 denoising training非常有效地稳定训练时期之间的二分匹配。去噪训练的关键思想是将带噪声的GT坐标…...
JPEG图像的压缩标准(1)
分3个博客详细介绍JPEG图像的压缩标准,包含压缩和解压缩流程,熵编码过程和文件存储格式。 一、JPEG压缩标准概述 JPEG压缩标准由国际标准化组织 (International Organization for Standardization, ISO) 制订,用于静态图像压缩。JPEG标准包…...
数解 transformer 之 self attention transformer 公式整理
句子长度为n;比如2048,或1024,即,一句话最多可以是1024个单词。 1, 位置编码 可知,E是由n个列向量组成的矩阵,每个列向量表示该列号的位置编码向量。 2, 输入向量 加入本句话第一个单词的词嵌入向量是, 第…...
ubuntu22.04@laptop OpenCV Get Started
ubuntu22.04laptop OpenCV Get Started 1. 源由2. 步骤3. 预期&展望4. 参考资料 1. 源由 OpenCV在学校的时候接触过,不过当时专注在物理、研究方面,没有好好的学习下。 这次借后续视频分析刚性需求,对OpenCV做个入门的学习和研读&#…...
【Java】苍穹外卖 Day01
苍穹外卖-day01 课程内容 软件开发整体介绍苍穹外卖项目介绍开发环境搭建导入接口文档Swagger 项目整体效果展示: 管理端-外卖商家使用用户端-点餐用户使用当我们完成该项目的学习,可以培养以下能力: 1. 软件开发整体介绍 作为一名软件开…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
