HTTPS 的加密流程

devtools/2024/10/19 9:43:22/

加密的⽅式有很多,但是整体可以分成两⼤类:对称加密和⾮对称加密

对称加密

对称加密其实就是通过同⼀个"密钥",把明⽂加密成密⽂,并且也能把密⽂解密成明⽂.

⼀个简单的对称加密,按位异或

 假设明⽂a=1234,密钥key=8888

 则加密a^key得到的密⽂b为9834.

 然后针对密⽂9834再次进⾏运算b^key,得到的就是原来的明⽂1234.

(对于字符串的对称加密也是同理,每⼀个字符都可以表⽰成⼀个数字)

当然,按位异或只是最简单的对称加密.HTTPS中并不是使⽤按位异或.

https>https://i-blog.csdnimg.cn/direct/cc0c904c21634497b67166ae89553f98.png" width="1200" />

引⼊对称加密之后,即使数据被截获,由于⿊客不知道密钥是啥,因此就⽆法进⾏解密,也就不知道请求 的真实内容是啥了.

但事情没这么简单.服务器同⼀时刻其实是给很多客⼾端提供服务的.这么多客⼾端,每个⼈⽤的秘钥都

必须是不同的(如果是相同那密钥就太容易扩散了,⿊客就也能拿到了).因此服务器就需要维护每个客⼾ 端和每个密钥之间的关联关系,这也是个很⿇烦的事情~

https>https://i-blog.csdnimg.cn/direct/865174e73713457dbc47750cb6d0086d.png" width="1200" />

⽐较理想的做法,就是能在客⼾端和服务器建⽴连接的时候,双⽅协商确定这次的密钥是啥~https>https://i-blog.csdnimg.cn/direct/8e07f6c0de444f15837ca5b5e7bfe64c.png" width="1200" />

按照这样的传输模式,密钥明文传输给服务器,此时黑客就可能截获到这个密钥后续的加密形同虚设.

但是要想对密钥进⾏对称加密,就仍然需要先协商确定⼀个"密钥的密钥".这就成了"先有鸡还是先有 蛋"的问题了.此时密钥的传输再⽤对称加密就⾏不通了. 

就需要引⼊⾮对称加密.

非对称加密

⾮对称加密要⽤到两个密钥,⼀个叫做"公钥",⼀个叫做"私钥". 

公钥和私钥是配对的.最⼤的缺点就是运算速度⾮常慢,⽐对称加密要慢很多.

• 通过公钥对明⽂加密,变成密⽂

• 通过私钥对密⽂解密,变成明⽂

也可以反着⽤

• 通过私钥对明⽂加密,变成密⽂

• 通过公钥对密⽂解密,变成明⽂

⾮对称加密的数学原理⽐较复杂,涉及到⼀些数论相关的知识.这⾥举⼀个简单的⽣活上的例⼦.

A要给B⼀些重要的⽂件,但是B可能不在.于是A和B提前做出约定:

B说:我桌⼦上有个盒⼦,然后我给你⼀把锁,你把⽂件放盒⼦⾥⽤锁锁上,然后我回头拿着钥匙来开锁 取⽂件.

在这个场景中,这把锁就相当于公钥,钥匙就是私钥.公钥给谁都⾏(不怕泄露),但是私钥只有B⾃⼰持 有.持有私钥的⼈才能解密.

https>https://i-blog.csdnimg.cn/direct/e922b40455dc4c178ffcb1d1f645a618.png" width="1200" />

• 客⼾端在本地⽣成对称密钥,通过公钥加密,发送给服务器.

• 由于中间的⽹络设备没有私钥,即使截获了数据,也⽆法还原出内部的原⽂,也就⽆法获取到对称密 钥

• 服务器通过私钥解密,还原出客⼾端发送的对称密钥.并且使⽤这个对称密钥加密给客⼾端返回的响 应数据.

• 后续客⼾端和服务器的通信都只⽤对称加密即可.

由于该密钥只有客⼾端和服务器两个主机知道,其他主机/设备不知道密钥即使截获数据也没有意义.由于对称加密的效率⽐⾮对称加密⾼很多,因此只是在开始阶段协商密钥的时候使⽤⾮对称加密,后续 的传输仍然使⽤对称加密.

那么接下来问题⼜来了:

• 客⼾端如何获取到公钥?

• 客⼾端如何确定这个公钥不是⿊客伪造的?

中间人攻击

⿊客可以使⽤中间⼈攻击,获取到对称密钥.

1. 服务器具有⾮对称加密算法的公钥S,私钥S'

2. 中间⼈具有⾮对称加密算法的公钥M,私钥M'

3. 客⼾端向服务器发起请求,服务器明⽂传送公钥S给客⼾端

4. 中间⼈劫持数据报⽂,提取公钥S并保存好,然后将被劫持报⽂中的公钥S替换成为⾃⼰的公钥M, 并将伪造报⽂发给客⼾端

5. 客⼾端收到报⽂,提取公钥M(⾃⼰当然不知道公钥被更换过了),⾃⼰形成对称秘钥X,⽤公钥M加 密X,形成报⽂发送给服务器

6. 中间⼈劫持后,直接⽤⾃⼰的私钥M'进⾏解密,得到通信秘钥X,再⽤曾经保存的服务端公钥S加 密后,将报⽂推送给服务器

7. 服务器拿到报⽂,⽤⾃⼰的私钥S'解密,得到通信秘钥X

8. 双⽅开始采⽤X进⾏对称加密,进⾏通信。但是⼀切都在中间⼈的掌握中,劫持数据,进⾏窃听甚⾄修改,都是可以的

https>https://i-blog.csdnimg.cn/direct/7a2196e0001c4547ab3a950c836591c6.png" width="1200" />

证书

服务端在使⽤HTTPS前,需要向CA机构申领⼀份数字证书,数字证书⾥含有证书申请者信息、公钥信 息等。服务器把证书传输给浏览器,浏览器从证书⾥获取公钥就⾏了,证书就如⾝份证,证明服务端公钥的权威性

https>https://i-blog.csdnimg.cn/direct/a8e1dfdff36b4669a9e9d6373add02d7.png" width="937" />

这个证书可以理解成是⼀个结构化的字符串,⾥⾯包含了以下信息:

• 证书发布机构

• 证书有效期

• 公钥

• 证书所有者

• 签名

• ......

需要注意的是:申请证书的时候,需要在特定平台⽣成查,会同时⽣成⼀对⼉密钥对⼉,即公钥和私 钥。这对密钥对⼉就是⽤来在⽹络通信中进⾏明⽂加密以及数字签名的。

理解数据签名

签名的形成是基于⾮对称加密算法的,注意,⽬前暂时和https>https没有关系,不要和https>https中的公钥私钥搞混了

https>https://i-blog.csdnimg.cn/direct/6bdbdf857ba14d8fa552810bdab5d52f.png" width="880" />

当服务端申请CA证书的时候,CA机构会对该服务端进⾏审核,并专⻔为该⽹站形成数字签名,过程如 下:

1. CA机构拥有⾮对称加密的私钥A和公钥A'

2. CA机构对服务端申请的证书明⽂数据进⾏hash,形成数据摘要

3. 然后对数据摘要⽤CA私钥A'加密,得到数字签名S

服务端申请的证书明⽂和数字签名S共同组成了数字证书,这样⼀份数字证书就可以颁发给服务端了

通过证书解决中间人攻击

在客⼾端和服务器刚⼀建⽴连接的时候,服务器给客⼾端返回⼀个证书.这个证书包含了刚才的公钥,也包含了⽹站的⾝份信息.

https>https://i-blog.csdnimg.cn/direct/31c14f4569c9443d8802dad3482857bc.png" width="1200" />

当客⼾端获取到这个证书之后,会对证书进⾏校验(防⽌证书是伪造的).

• 判定证书的有效期是否过期

• 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).

• 验证证书是否被篡改:从系统中拿到该证书发布机构的公钥,对签名解密,得到⼀个hash值(称为数 据摘要),设为hash1.然后计算整个证书的hash值,设为hash2.对⽐hash1和hash2是否相等.如果相等,则说明证书是没有被篡改过的.


http://www.ppmy.cn/devtools/121947.html

相关文章

【C++复习】C++11经典语法

文章目录 {}列表初始化1. 初始化内置类型变量2. 初始化数组3. 初始化标准容器4. 初始化自定义类型5. 构造函数初始化列表6. 初始化列表(initializer_list)7. 返回值初始化8. 静态成员变量和全局变量的就地初始化9. 防止类型收窄总结 decltype右值引用完美…

hdu-6024

hdu-6024 struct node {int x, c;bool operator<(const node &a) const{return x < a.x;} }; // dp[i][0]为到第i个教室且第i个教室不建糖果店的花费前缀和&#xff0c;dp[i][1]为到第i个教室且第i个教室建糖果店的花费前缀和 int dp[N][2]; void solve() {int n;wh…

信号处理: Block Pending Handler 与 SIGKILL/SIGSTOP 实验

1. 信号处理机制的 “三张表” kill -l &#xff1a;前 31 个信号为系统标准信号。 block pending handler 三张表保存在每个进程的进程控制块 —— pcb 中&#xff0c;它们分别对应了某一信号的阻塞状态、待处理状态以及处理方式。 block &#xff1a;通过 sigset_t 类型实现&…

【CCPC】The 2024 Shanghai Collegiate Programming Contest F

羁绊大师 #动态规划 #图论 #并查集 #背包 题目描述 在某一自走棋游戏中&#xff0c;胖胖龙此刻拥有 n n n 个英雄&#xff0c;其中第 i i i 个英雄拥有两种羁绊&#xff0c;分别为 a i , b i ( a i < b i ) a_i, b_i(a_i < b_i) ai​,bi​(ai​<bi​) 不存在两个…

使用rust写一个Web服务器——多线程版本

文章目录 模拟慢请求多线程Web服务器实现为每个请求单独生成一个线程限制创建线程的数量ThreadPool的初始化ThreadPool的存储ThreadPool的设计 关闭和资源清理为ThreadPool实现Drop停止工作线程测试 仓库地址&#xff1a; 1037827920/web-server: 使用rust编写的简单web服务器 …

拓扑排序简介

拓扑排序(Topological Sort)是一种重要的图算法,用于对有向无环图(DAG, Directed Acyclic Graph)中的节点进行排序。拓扑排序的结果是一种线性序列,使得对于图中的任意一条有向边(u, v),顶点u都在顶点v之前。这种排序常用于任务调度、编译器依赖关系分析等领域。 拓…

程序计数器(学习笔记)

程序计数器是一块较小的内存空间&#xff0c;它的作用可以看做是当前线程所执行的字节码的信号指示器&#xff08;偏移地址&#xff09;&#xff0c;Java编译过程中产生的字节码有点类似编译原理的指令&#xff0c;程序计数器的内存空间存储的是当前执行的字节码的偏移地址 因为…

linux网络编程实战

前言 之前找工作的之后写了一些网络编程的笔记和代码&#xff0c;然后现在放到csdn上保存一下。有几个版本的&#xff0c;看看就好。就是简单的实现一下服务端和客户端之间的交互的&#xff0c;还没有我之前上linux编程课写的代码复杂。 哦对了&#xff0c;这个网络编程的代码对…