基于 RSA 非对称加密与挑战码机制的前端登录安全方案

基于 RSA 非对称加密与挑战码机制的前端登录安全方案

一、背景与目标

在传统登录实现中,即使使用 HTTPS 进行传输加密,仍存在以下潜在风险:

  • 代理或中间件解密 HTTPS 流量后,明文密码暴露在中间层
  • 攻击者截获合法请求后进行重放攻击
  • 数据库中密码以弱哈希形式存储,泄露后易被彩虹表破解

本方案通过引入 RSA 非对称加密与一次性挑战码机制,在现有 SHA256 密码存储体系下,构建一套兼具传输安全与防重放能力的前端登录流程。


二、方案概述

整体方案由以下三个核心机制组成:

  • SHA256 哈希:与数据库存储格式保持一致,避免明文密码在网络中传输
  • RSA-OAEP 非对称加密:使用公钥对登录凭证加密,只有持有私钥的服务端才能解密
  • 一次性挑战码(Challenge):每次登录请求绑定唯一挑战码,验证后立即销毁,从根本上防止重放攻击

三、完整登录流程

3.1 获取挑战码

前端在发起登录请求前,首先向服务端请求一次性挑战码:

复制代码
GET /auth/challenge

服务端生成随机 challengeId 与对应的 challenge 值,存入 Redis 并设置 30 秒 TTL,随后返回给前端。


3.2 前端加密处理(两次加密)

前端收到挑战码后,依次执行两步加密操作:

第一步:SHA256 哈希密码

复制代码
sha256Hash = SHA256(用户明文密码)

此步骤将密码转换为与数据库存储值一致的哈希,避免明文密码在任何环节暴露。

第二步:RSA-OAEP 公钥加密

复制代码
ciphertext = RSA_OAEP_encrypt(sha256Hash + ":" + challengeId, 公钥)

将哈希结果与 challengeId 以冒号拼接后整体加密。公钥内置于前端代码中,不动态下发,防止中间人替换公钥。加密算法必须使用 RSA-OAEP(配合 SHA-256),严禁使用存在 Bleichenbacher 攻击漏洞的 PKCS#1 v1.5。


3.3 发送登录请求

前端仅发送用户名与密文,challengeId 隐藏在密文内部,不在请求体中明文暴露:

复制代码
POST /auth/login

{
  "username": "alice",
  "ciphertext": "<RSA加密后的密文>"
}

3.4 服务端验证流程

服务端收到请求后,按以下步骤进行验证:

① RSA 私钥解密

复制代码
plaintext = RSA_私钥解密(ciphertext)
[sha256Hash, challengeId] = plaintext.split(":")

② 校验挑战码有效性

从 Redis 中查询 challengeId 对应记录,若不存在或已过期则拒绝请求;查询成功后立即删除该记录,确保挑战码一次性不可复用。

③ 校验密码哈希

将解密得到的 sha256Hash 与数据库中存储的哈希值进行比对,一致则验证通过。

④ 下发 Token

验证通过后生成 JWT Token 返回给前端,完成登录。


四、安全性分析

攻击场景 防护效果 说明
网络抓包重放 ✅ 有效防护 密文不可复用,challengeId 一次性销毁
中间人篡改请求 ✅ 有效防护 无私钥无法构造有效密文
HTTPS 代理解密后重放 ✅ 有效防护 挑战码已失效,重放请求被拒绝
数据库泄露 ⚠️ 部分风险 SHA256 无盐存储仍有彩虹表风险,建议迁移至 BCrypt
服务端私钥泄露 ❌ 全线失效 私钥需严格保管,建议配合 HSM 使用

五、关键设计要点

  • RSA 密钥长度:最低 2048 bit,推荐 4096 bit
  • 加密模式:必须使用 RSA-OAEP + SHA-256,禁止 PKCS#1 v1.5
  • 公钥分发:内置于前端构建产物,不通过接口动态下发
  • 挑战码生命周期:有效期 30 秒,验证后立即从 Redis 删除
  • challengeId 隐藏:包含在密文中,不在请求参数中明文暴露
  • 时序安全:服务端比较哈希时使用恒定时间比较函数,防止时序攻击

六、后续优化建议

  • 密码存储迁移:将现有 SHA256 存储升级为 BCrypt 或 Argon2,加入随机盐值,从根本上消除彩虹表威胁
  • 私钥管理:将 RSA 私钥存储于 HSM(硬件安全模块)或 KMS(密钥管理服务),避免私钥直接落盘
  • 登录限频:结合 IP 限流与账号锁定策略,防止暴力破解
  • 长期演进:如需彻底消除服务端接触密码哈希,可评估引入 SRP(Secure Remote Password)协议
相关推荐
ZC跨境爬虫1 小时前
跟着 MDN 学 HTML day_39:(DOMException 异常接口完全解析)
前端·javascript·html·媒体
渐儿1 小时前
NestJS 教程 Part 2 — 数据层、API 设计与业务异步
前端
渐儿1 小时前
Next.js 教程 Part 2 — 数据获取、Server Actions 与状态
前端
Magic-Yuan1 小时前
LLM 十大安全风险 - 概述
人工智能·安全
用户125758524361 小时前
XYGo Admin ArtTable 表格组件:一行代码搞定加载、刷新与分页
前端
gogoing2 小时前
Prettier 配置说明
前端·javascript
十有八七2 小时前
Hermes Agent 自进化实现:从源码到架构的深度拆解
前端·人工智能
渐儿2 小时前
NestJS 生产级开发教程
前端
前端毕业班2 小时前
uni-app onShareAppMessage hook 原理分析
前端·javascript