【干货】如何实现安全的登录系统:从用户登录场景分析 Web 网络安全技术

安全的登录系统

为何不安全

当用户在前端输入密码账号后,要把信息发往服务端完成注册/登录,数据需要经过互联网的“黑暗森林”。
在互联网中, CSRF(跨站伪造请求伪造)、XSS(跨站脚本攻击)、MITM(中间人攻击)、RA(请求重放攻击) 等各种不怀好意的程序可在某处窥伺着这份数据。

然后不少刚入门的开发者还在把自己的登录用明文传输!

现在,让我们来谈一谈,如何从明文传输不断改进,打造一个高安全系数的登录系统。

君の安全基本技巧本当上手

1. 摘要

1.1 什么是摘要

简单理解:摘要就是 Hash,也就是把 A 单向映射 B,所谓的单向就是指 B 无法逆向推导出 A。

一个简单的代码例子:

function myHash(value1) {let value2 = 0;for (let i = 0; i <= value1; i++) {value2 += i;}    return value2 % 100; // 为了简化,取模100
}
const A1 = 100;
const B1 = myHash(A1); // 50const A2 = 99;
const B2 = myHash(B2); // 50

如果知道 A 的值,那么这里可以推导出 B 的值;
但是如果只知道 B 的值,那么是没有办法知道 A 具体的值的,比如这里 B 是 50,我们也不知道它对应的 A 到底是 99 还是 100 或者别的数。

我们常常说的什么 MD5, 冲突散列表 base64、哈夫曼编码之类的,其实都是一种摘要算法。

1.2 摘要的作用

摘要有一个特点就是,输入哪怕只变动一点,输出也可能会有巨大的变化,让人找不到规律。

这样就可以也就可以防止数据被篡改,保证其完整性。

具体到登录场景,前端可以先用 base64 把数据 data 摘要得到一个 hash1,再把两者一起发给后端。
后端拿到数据后,也把 data 用 base64 摘要,得到 hash2,再对比 hash1 和 hash2,如果一样,就说明 data 没有被篡改过。

这时候,有人就会说了——“这也没用啊,人家都能改你 data 了,那直接把你 hash 一起改了不就完了”

诶,好东西总是成套的,要想更安全,还得搭配其他技巧凑成丝滑小连招。

2. 密钥加密

2.1 对称加密 与 非对称加密

加密就像是一把锁。

  1. 对称加密: 同一把钥匙,能上锁加密,也能解锁解密。
  2. 非对称加密:两种钥匙,一种钥匙只能开锁,另一种钥匙只能解锁。

这里的钥匙,都叫做密钥

一个冷知识是,这里的 “钥” 的官方读法是 “yue”。
但是个人还是习惯读作密 “yao” ,因为读作 “蜜月” 总感觉怪怪的。

对称和非对称这两个概念的比喻已经非常形象了,所以我认为也无需过多解释。

我们接着来说说非对称加密种的两种钥匙:

2.2 公钥 与 私钥

其实也是非常所见即所得的概念:

公钥:可以公开的钥匙就是公钥,发给大家用的。
私钥:只有自己或者少数人可以有的就是私钥,是不可以公开的。

那么,非对称加密种,究竟是【加密密钥】作为公钥呢,还是【解密密钥】做公钥呢(另一种钥匙则为私钥)?答案是,两种情况都可以

这里我们进一步介绍下两种情况:

2.4 私钥加密-公钥解密:验证私钥拥有者的身份

这就是说,全世界都可以解密某个密文,但是只有一个人可以产生这种密文——这就实现了(私钥拥有者的)身份验证。

有什么用呢?如果你用过 Github 的 SSH,那就会恍然大悟了——你只需要生成一个密钥对,用其中的私钥来给你的计算机生成一个密文,然后把公钥交给 Github 之类的网站,这些网站就能通过上面说的那样来验证你的身份了。

2.3 公钥加密-私钥解密:构建安全信息通道

这意味着,所有人都能加密数据,而只有少数群体能解密数据,也就是说,数据只有在拥有解密私钥的人手里才是真正有效的——这样一来,从公钥群体传输到私钥群体这个路径,就是一条所谓的安全信道(安全信息通道)了。

我们的登录场景就可以使用这个模式,把用户的数据 data 先摘要得到 hash, 保证它是完整的,同时也避免了明文传输,再把.hash 用服务端的公钥加密得到密文sec_data,然后再发送。

这样一来,就算是被恶意程序获取到了我们的数据,它们也没法修改、解读我们的代码了,真是十分美好呢!

但是,这样就真的安全了吗?万一我们的数据被中间人拦截了呢?

2.4 中间人攻击 & 请求重放攻击 & 撞库攻击

中间人可以横在前端与服务端之间,然后再根据自己的心情做事:

  • 直接攻击:把请求干掉,或者篡改掉(当然,这里我们已经初步防止了这种问题)。
  • 非法收集数据:悄无声息地把每一份经过的数据复制一份,或者原封不动地把请求继续发给服务端。

当然,非法收集数据的不一定是中间人…安全技术任重道远…

对于非法收集数据这一点,有小伙伴就会问了——”我们不是把数据加密过了吗?上一章节才说了安全信道,它拿到的都是密文,是不是就没用呢?“

当然不是的,中间人如果把我们的登录请求原封不动复制一份,那么即使它不知道密码,它也可以直接使用这个请求完成非法用户登录,这就是请求重放攻击。

除此之外,如果它收集了足够多的数据,而我们的加密策略又是多年不变的话,那么经过不法分子们的分析,加密算法就可能被部分破解,随之而来的可能就是超多脚本自动疯狂尝试不同的密码进行登录,这就是撞库攻击,轻则少量用户密码泄露,重则整个加密规则被破解,最后在某个不知名的灰色地带,就会产生一张彩虹表,详细记录着所有用户的密码信息…

问题很多,但是我们不要急,我们一个一个来解决——这里根据我们分析,中间人攻击会衍生出更多问题,它的危害较大,所以优先处理:

2.5 CA 证书:活学活用密钥加密

对于中间人攻击,我们应该思考的第一个问题是,为什么会出现中间人?说到底还是没验证下游的身份,就稀里糊涂把数据交了出去。

那怎么验证身份呢?还记得我们上面说的私钥加密-公钥解密么?其实也很好办,就是每次交出数据前,让下游给我们一个密文,我们常使用之前约定好的公钥尝试解密它,如果能得到有效信息,那说明下游服务就是货真价实的。

但是,如果我们更阴谋论一点想一想,“你怎么证明你自己是你自己”——万一最开始的时候,这个公钥就是伪造的呢?万一最开始和我做约定的,就是中间人呢?

灵魂拷问:你如何证明你是你自己?

如果没法自证清白,那就得请出权威机构来鉴定一下了——这就是CA 机构。

按照现代社会的网络规范来说,每个服务器都得向 CA 机构去申请认证,然后得到一个 CA证书,这个申请过程是这样的:

生成密钥对:服务器首先生成一对公钥和私钥。
申请证书:服务器向 CA 申请证书,提交自己的公钥和身份信息,CA 会对这些信息展开调查验证。
产生 CA 证书:CA 先对【服务器的公钥和身份信息】进行摘要,然后对摘要的得到的 hash 用【CA自己的的私钥】进行加密,这种【摘要+密钥加密】的操作就叫签名。(得到的产物也叫签名,就是一个动词和名词的区别)

再具体一点就是这样的:

// 生成摘要
输入数据: "公钥: ABCD1234, 身份信息: example.com,颁发 CA 机构:xxx, ....."
哈希函数: SHA-256
摘要: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855// 生成签名
私钥: CA的私钥
摘要: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
签名: 1f4e6a7b8c9d0e1f2e3d4c5b6a7b8c9d0e1f2e3d4c5b6a7b8c9d0e1f2e3d4c5b

这个证书是可以给所有人访问的,包含了三个部分:

  • 服务器的公钥:因为服务器无法证明“自己是自己”,所以公钥和私钥都由CA 官方来它发一个,(当然,私钥是不会出现在CA证书上的,而是由服务器自己保管好)
  • 服务器信息:介绍了服务器的一些基本情况,以及数字签名用到的一些摘要算法
  • 数字签名:一个字符串,产生的方式是:1. 将上面两部分作为参数进行摘要得到一个 hash,保证数据不可被篡改。2. 然后再用 【CA 给的私钥】 加密,生成一个字符串,也就是所谓的数字签名了。

有了这个机制,如果我们默认 CA 机构足够权威可信,那么我们访问下游服务的时候就会先让它出示 CA 证书,然后我们需要判断证书的真伪:

  1. 用户先从某处(下文会提到)获取**【CA的公钥】**——这是计算机出厂后装系统时自动内置的,然后用它把数字签名给解密,还原到摘要hash
  2. 然后阅读CA机构鉴定过的【服务器信息】,得到其中使用的摘要算法,用这个算法把【服务器公钥】和【服务器信息】作为参数进行摘要,得到hash1,对比hash1和hash,如果一致,就说明数据没被篡改过。

这样一来,有了 CA 的认证,服务器就可以排除嫌疑了——等等,万一这个 CA 机构是假的呢?

这里就得解释上文中提到的某处是什么了:

  1. 计算机出厂后,安装系统时,会把一些最最最权威的【CA 机构自己的证书(结构跟上面大体一样)】一起内置到系统中,这也就是所谓的某处。当然,浏览器也类似,会内置 CA 机构证书。
  2. CA 机构 也有三六九等的,【有一点点权威的CA】需要【更有权威的CA】来颁发证书认证(流程跟上面一样),而我们系统/浏览器内置的都是【最大权威】的——这样的关系就叫做,CA信任链。
  3. 当我们从服务器拿到一个野生证书的时候,就会根据证书中的【服务器信息】来逐步向上查找它的最终颁发机构,如果这个机构是我们系统/浏览器中内置的【最大权威】的机构之一的话,就说明它是真的。

绕了这么多弯,我们终于能够证明下游服务是真实可信的了。——而这一切的基础是 我们始终相信【最大权威】的 CA 是可信的,

不然,几乎无法建立完全可信的网络体系(或许区块链能够带来一些新的可能?)。

就这样,绝大部分中间人攻击被避免了(但是网络安全就没有绝对的事情)。

2.6 防碰撞随机数 与 加盐

为了应对重放攻击,我们会在登录请求前,先额外提前请求让服务端生成一个一次性随机数,之后登录请求时,在某处带上这个随机数交给服务端,服务端会验证随机数是否有效,如果有效的话就核销这个随机数让它不可再使用第二次。

  • 在这个场景下,我们把一次性随机数作为防碰撞随机数使用,但是二者并不是完全一样的概念(防碰撞不一定要用一次性随机数)
  • 当然这里可能又有同学要问了,万一下发这个随机数的时候又被中间人拦截了——我们在上一章已经解决了中间人问题,所以这里不需要有这种担心。
  • 我们这里讨论的也是【通过非中间人的手段获取到登录请求】进而发动的重放攻击——比如在用户本地注入了恶意脚本,在其浏览器中抓包。不过这也是非常尴尬的一点,这些恶意脚本通常都能够发动更直接的攻击,而不需要再使用重放攻击了——我们这里就当作是为了学习知识而强行说有这种重放攻击的可能吧。

这里的某处有很多选择,比如可以是 http header 中带上一个 token,也可以是在用服务端的公钥将密码hash加密时,顺带把随机数也作为参数加密。

具体怎么做,具体场景需要具体分析

最后,在落库前,我们需要把 hash 值加盐。

加盐是指,在原始数据的固定位置上加入随机内容。
同过加盐,我们使得最终的输出的结果出现差异
这样就避免了多个用户都用一个密码导致hash值一样的情况,见笑了撞库的可能。

再等等,课本里面告诉我们 HTTPS 是能有效避免中间人攻击的,但这里怎怎么只说 CA 一点没提到 HTTPS 呢?原来,摘要,密钥加密,包括 CA 证书,防碰撞随机数,还有加盐,都是 HTTPS 的一环。

2.6 HTTPS: 上述章节都只是我的其中一环

既然都说到了 HTTPS 了,那不妨顺带把 HTTP 一起回顾了,而既然都说到了 HTTP 了,那干脆从 TCP 三次握手讲起:

TODO: 这部分后面回头补上

知识加餐

如果你对 Rust、Web、服务等知识点感兴趣,也欢迎看看我的其他文章,这里只推荐干货,绝不啰嗦:

Docker快速上手:【安装/配置/使用/原理】一条龙教程
Rust 字符串(可变字符串String与字符串切片&str)
Rust 智能指针

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

静态数据区,堆,栈

在 C/C 中&#xff0c;静态数据区、堆、栈是不同的内存区域&#xff0c;它们的用途和管理方式各不相同。以下是它们的区别&#xff1a; 1. 静态数据区 存储内容&#xff1a;静态数据区用于存储全局变量和静态变量&#xff0c;包括在编译期就确定的变量值&#xff08;如常量&a…

python 五子棋小游戏

1. 实现效果 Python五子棋小游戏 2. 游戏规则 规则说明&#xff0c;五子棋人机对战游戏规则如下&#xff1a;‌ Ⅰ 默认规则 - 五子棋规则 对局双方‌&#xff1a;各执一色棋子&#xff0c;一方持黑色棋子&#xff0c;另一方持白色棋子。棋盘与开局‌&#xff1a;空棋盘开局…

Qt Modbus 2 通信实现

上一文章主要了解下Modbus协议和事务处理流程&#xff0c;本章则直接贴放代码实现qt 上位机与温控器通讯。项目主要实现定时读取温度、设置温度、开始加热和停止加热四个功能。 采用的是 Modbus Rtu 通信 1 Qt modbus 模块依赖 QT serialbus serialport 源代码 .h文件 #i…

033_Structure_Static_In_Matlab求解结构静力学问题两套方法

结构静力学问题 静力学问现在是已经很简单的问题&#xff0c;在材料各向同性的情况下&#xff0c;对于弹性固体材料&#xff0c;很容易通过有限元求解。特别是线弹性问题&#xff0c;方程的矩阵形式可以很容易的写出&#xff08;准确得说是很容易通过有限元表达&#xff09;&a…

rnn/lstm 项目实战

tip:本项目用到的数据和代码在https://pan.baidu.com/s/1Cw6OSSWJevSv7T1ouk4B6Q?pwdz6w2 1. RNN : 预测股价 任务&#xff1a;基于zgpa_train.csv数据,建立RNN模型,预测股价 1.完成数据预处理&#xff0c;将序列数据转化为可用于RNN输入的数据 2.对新数据zgpa_test.csv进…

jenkins 构建报错 mvn: command not found

首先安装过 maven&#xff0c;并且配置过环境变量 win r ,输入 cmd 键入 mvn -v 出现上图输出&#xff0c;则证明安装成功。 原因 jenkins 没有 maven 配置全局属性, 导致无法找到 mvn 命令。 解决方案 找到全局属性&#xff0c;点击新增&#xff0c;配置 MAVEN_HOME 路…

轮廓图【HTML+CSS+JavaScript】

给大家分享一个很好看的轮播图&#xff0c;这个也是之前看到别人写的效果感觉很好看&#xff0c;所以后面也自己实现了一下&#xff0c;在这里分享给大家&#xff0c;希望大家也可以有所收获 轮播图效果&#xff1a; 视频效果有点浑浊&#xff0c;大家凑合着看&#xff0c;大家…

ChatGPT变AI搜索引擎!以后还需要谷歌吗?

前言 在北京时间11月1日凌晨&#xff0c;正值ChatGPT两岁生日之际&#xff0c;OpenAI宣布推出最新的人工智能搜索体验&#xff01;具备实时网络功能&#xff01;与 Google 展开直接竞争。 ChatGPT搜索的推出标志着ChatGPT成功消除了即时信息这一最后的短板。 这项新功能可供 …

Linux系统性能调优

在Linux系统中&#xff0c;性能调优是确保系统高效运行的重要任务。优化可以涵盖多个方面&#xff0c;包括文件系统、内存管理、网络和进程管理等。以下是一些常用的Linux性能调优策略&#xff1a; 1. 系统监控工具 在开始优化之前&#xff0c;首先需要监控系统的性能&#x…

Netty 组件介绍 - ByteBuf

直接内存&堆内存 ByteBuf buffer ByteBufAllocator.DEFAULT.heapBuffer(10);ByteBuf byteBuf ByteBufAllocator.DEFAULT.directBuffer(10); 组成 ByteBuf维护了两个不同的索引&#xff0c;一个用于读取&#xff0c;一个用于写入。 写入 内存回收 堆内存使用的是JVM内…

都快2025年了,来看看哪个编程语言才是时下热门吧

早上好啊&#xff0c;大佬们&#xff0c;今天咱们不讲知识&#xff0c;今天我们来看看时下热门的编程语言都是哪些&#xff0c;大佬们又都是在学哪些语言呢。 最近一些朋友和我在讨论哪个编程语言是现在 最好用 最厉害 的编程语言。 有人说&#xff0c;Python简单好用&#xf…

【雷达信号数据集】雷达脉冲活动分段的多级学习算法【附下载链接】

摘要 无线电信号识别是电子战中的一项重要功能。电子战系统需要精确识别和定位雷达脉冲活动&#xff0c;以产生有效的对抗措施。尽管这些任务很重要&#xff0c;但基于深度学习的雷达脉冲活动识别方法在很大程度上仍未得到充分探索。虽然之前已经探索了用于雷达调制识别的深度…

vscode php Launch built-in server and debug, PHP内置服务xdebug调试,自定义启动参数配置使用示例

在vscode中&#xff0c;当我们安装了插件 PHP Debug&#xff08;xdebug.php-debug&#xff09;或者 xdebug.php-pack 后 我们通过内置默认的 php xdebug配置启动php项目后&#xff0c;默认情况下我们在vscode中设置断点是不会生效的&#xff0c;因为我们的内置php服务默认启动时…

(二 上)VB 2010 设计初步

目录 一、常用类应用 1.Console类控制台 2.窗体基本控件 二、面向对象程序设计 1.类和对象 2.对象的属性、方法、事件属 1.属性 2.方法 3.事件、事件过程 1.事件 2.事件过程 3.对象浏览器 三、.NET类库与命名空间 1.命名空间 常用命名空间 1.System命名空间 2.…

[CARLA系列--01]CARLA 0.9.15 在Windows下的安装教程(一)

Carla是一款开源的自动驾驶仿真器&#xff0c;它基本可以用来帮助训练自动驾驶的所有模块&#xff0c;包括感知系统&#xff0c;Localization, 规划系统等等.Carla这个产品目前已经更新到了最新的0.9.15版本,目前遇到好多人在windows系统上如何安装可编辑版的Carla遇到了好多问…

禾川HCQ1控制器程序编译报错如何解决

1、第一次打开用户程序 2、提示库未安装 3、安装库文件 4、脉冲轴库未安装 5、没有错误 去禾川自动化官网,把可以安装的包和库都安装下,程序编译就没有错误了。 6、下载相关包文件

Go语言sync.WaitGroup与errgroup.Group用法详解

errgroup.Group 和 sync.WaitGroup 的主要区别在于它们的错误处理和协程管理方式。 errgroup.Group 专为并发操作中的错误捕获设计&#xff0c;任意goroutine返回错误时&#xff0c;会立即终止其他goroutine的执行。 而 sync.WaitGroup 主要用于等待多个 goroutine 完成&…

ubuntu20安装opencv3.2记录

系统环境 ubuntu20安装了ros-noetic&#xff0c;所以系统默认装了opencv4.2.0&#xff0c;但是跑fastlivo推荐的是opencv3.2.0&#xff0c;而且海康相机别人写的ros驱动&#xff08;海康相机ros驱动&#xff09;也是需要opencv3.2.0&#xff0c;最终还是选择安装多版本的openc…

基于NVIDIA NIM平台实现盲人过马路的demo(一)

前言:利用NVIDIA NIM平台提供的大模型进行编辑,通过llama-3.2-90b-vision-instruct模型进行初步的图片检测 step1: 部署大模型到本地,引用所需要的库 import os import requests import base64 import cv2 import time from datetime import datetimestep2: 观看官方使用文…

MATLAB下的四个模型的IMM例程(CV、CT左转、CT右转、CA四个模型),附源代码可复制

文章目录 基于IMM算法的目标跟踪概述源代码运行结果代码结构与功能1. 初始化2. 仿真参数设置3. 模型参数设置4. 生成量测数据5. IMM算法初始化6. IMM迭代7. 绘图8. 辅助函数总结基于IMM算法的目标跟踪 概述 该MATLAB代码实现了基于交互式多模型(IMM)算法的目标跟踪,旨在估…