【Linux网络编程】应用层协议-----HTTPS协议
文章目录
- 一、前置知识:
- 1、HTTP的缺陷:
- 2、中间人:
- 3、数据加密与密钥:
- 密钥:
- 数据加密:
- 4、数据摘要:
- 二、深度理解HTTPS加密过程:
- 1、方案一-----只使用对称加密:
- 2、方案二-----只使用一个非对称加密:
- 3、方案三-----双方都使用非对称加密:
- 4、方案四-----使用对称加密和非对称加密:
- 5、MITM中间人攻击:
- 6、引入证书:
- 证书申请流程:
- 介绍证书:
- 数字签名:
- 7、方案五-----非对称加密+对称加密+证书认证
- 周边问题?
一、前置知识:
1、HTTP的缺陷:
已经有了HTTP那么为什么还有HTTPS,那么我们就需要知道HTTP的缺陷 ----- 它无论使用GET传参或者是POST传参都无法保证数据在传输过程中的安全问题,毕竟都是没有经过任何加密的,但是在互联网场景下,尤其是在支付,登录等隐私方面对安全问题很严格
HTTP的三个致命缺陷:
- 数据不加密:HTTP传输的所有信息都是明文的,没有任何加密处理
- 数据易篡改:HTTP没有数据是否被修改的校验机制,当被黑客截胡后进行修改,客户端和服务端都难以察觉
- 身份难验证:HTTP无法确认客户端连接的服务端是否是官方的,可能会被伪造
于是就诞生了HTTPS:
首先让我们来回忆数据的传输:
在数据的传输过程中,是自上向下,一层一层交付给对应层的,然后别的用户收到消息后一层一层向上进行解析,在整个传输中是明文的,并且可能能够被其他用户拿到数据,这样是很危险的
那么就需要在应用层中加上一个加密解密的功能
当HTTPS进行数据加密后,就能够保证数据的安全,但是不是百分百能够保证,当有黑客通过更强的算力攻破了当前版本的HTTPS方案,就需要官方的人员进行更新和维护了
2、中间人:
这个中间人并不是一个人,而是一种攻击角色或者攻击模式,它在客户端和服务端之间实现数据的拦截、窃取、篡改甚至伪造,而此时通信双方往往察觉不到异常
简单来说就是将通信连接从“你->服务端”变为“你->中间人->服务端”,这样所有数据都会经过中间人的手中,这样我们的信息、请求就暴露了
3、数据加密与密钥:
密钥:
密钥是进行加密解密的一串重要的秘密参数,其本质是一串特定格式的字符串或者字符,决定了加密算法如何将明文转换为密文,以及如何将密文还原为明文
比如,我们想将一个数字2发送给另一个客户端,我们规定我们的密钥为7,那么我就可以先对要发送的数据2进行加密,比如说2异或7然后得到一个数据,接着将这个数据发送给对应客户端,当对应客户端的到加密后的数据后,就会进解密,将2异或7然后在异或7这样就会得到原来的数据
在上述过程中,我们将2叫做传输的明文数据,将2异或7得到的数叫做密文,将7叫做密钥
数据加密:
为了将明文数据转为密文数据,那么就需要对明文数据进行加密,这个加密方法有两种:对称加密与非对称加密
- 对称加密:加密和解密使用同一把密钥
- 非对称加密:加密和解密使用一对不同但关联的密钥,分为公钥和私钥
对比维度 | 对称加密 | 非对称加密 |
---|---|---|
密钥数量与用途 | 1 把密钥(加密 + 解密) | 2 把密钥(公钥加密,私钥解密,也可以私钥加密,公钥解密) |
密钥传递安全性 | 需传递密钥,存在泄露风险 | 无需传递私钥,安全性高 |
加解密速度 | 快(适合大量数据) | 慢(适合小数据,如密钥传递) |
典型应用场景 | 数据传输(WiFi、文件传输) | 密钥交换、身份验证(HTTPS、数字签名) |
4、数据摘要:
它通过特定算法对任意长度的原始数据进行处理,最终生成一段固定长度、唯一对应原始数据的二进制或十六进制字符串,本质是为数据生成一份数字身份证,这是一种hash算法,这样生成的数据有很小概率发生哈希冲突的算法,最典型的有MD5算法
特性 | 核心解释 |
---|---|
固定长度输出 | 无论原始数据是 1KB 的文本,还是 10GB 的视频,同一算法生成的摘要长度完全相同 |
唯一性 | 不同原始数据生成相同摘要的概率极低(发生冲突的概率几乎为0),可认为一数据一摘要 |
不可逆性 | 只能从原始数据生成摘要,无法通过摘要反推回原始数据 |
敏感性 | 原始数据哪怕仅修改 1 个字节,生成的摘要也会发生天翻地覆的变化 |
二、深度理解HTTPS加密过程:
那么对于HTTPS的加密方案,是怎么进行加密的呢?我们一步一步推导
1、方案一-----只使用对称加密:
客户端和服务端都约定好一个密钥,那么双方在通信的时候就能够通过这个密钥进行加密,比如说客户端要给服务端发送数据,然后用密钥给这个数据进行加密,接着向服务端发送过去,即使在网络中被中间人拿到了,中间人是不知道密钥的,所以就无法解密,也就无法拿到数据了,服务端有着相同的密钥,在拿到数据后就能够进行解密,这样就能够拿到客户端的数据,并且这样也能够保证数据的安全了
但是真的能够保证安全吗?
客户端和服务端要约定好一个密钥,这个约定是怎么约定的呢?如果是服务端或者客户端通过网络进行通信,那么问题来了,进行通信的时候,中间人是不是就有可能能够拿到这个密钥呢?那么这个密钥也就会成为摆设了,那么就有人说能不能不通过网路通信,而是线下或者什么方式进行通知对方,但是这样也有缺陷,如果想要进行修改密钥,并且如果有多个客户端,那么修改的成本是很大的
综上,这个方法是行不通的
2、方案二-----只使用一个非对称加密:
首先服务端生成两个密钥,分别是公钥P和私钥P`,接着客户端请求服务端的公钥,然后客户端就会拿到公钥,然后客户端向服务端发送数据的时候,用公钥P进行加密形成密文,此时就算这个密文被中间人截获到,但是中间人只可能会有服务端的公钥,不会有私钥,所以中间人无法进行解析,当服务端收到客户端发来的密文后,因为服务端有私钥,就能够进行解析
那么就能够保证客户端到服务端的数据安全(真的吗?)
但是当服务端响应数据给客户端的时候,只能用私钥进行加密,因为客户端只有公钥,但是中间人也有公钥,那么就不能够保证服务端到客户端之间的数据安全
所以这种方法是不行的
3、方案三-----双方都使用非对称加密:
服务端有自己的公钥S和私钥S’,客户端也有自己的公钥C和私钥C’
公钥是公开的,很容易就能够拿到对方的公钥
那么客户端给服务端发数据的时候,用服务端的公钥进行加密,然后发送给服务端,那么就只有服务端能够解密
当服务端响应客户端的数据的时候,用客户端的公钥进行加密,然后响应给客户端,那么就只有客户端能够解密
上述过程乍一看没啥问题,但是因为都是使用的非对称加密,会导致效率非常低,并且也不绝对安全
4、方案四-----使用对称加密和非对称加密:
- 首先服务端生成自己的公钥S和私钥S’
- 接着客户端向服务端发起请求,请求服务端的公钥S
- 然后客户端在本地生成自己的对称密钥C,接着将自己的密钥C通过S进行加密形成密文,然后发送给服务端
- 即使中间人截获了数据,但是没有私钥S’,所以也就无法进行解密
- 当服务端拿到了数据后,可以用S’进行解密,也就拿到了客户端的密钥C,这样就能够通过这个密钥C进行数据通信了
由于对称加密比非对称加密的效率高,所以这样就能够解决都是用非对称加密的效率问题,但是依然是存在安全问题的
5、MITM中间人攻击:
Man-in-the-MiddleAttack,简称MITM攻击,也就是中间人攻击
在上述的方案中,有的咋一看是完美的,但是有一种都解决不了的问题:如果中间人一开始就在呢
- 首先服务端有自己的公钥S和密钥S’,中间人也有自己的公钥M和密钥M’
- 当客户端向服务端请求后,服务端给客户端响应公钥S,但是此时被中间人截获到了,将响应中的服务端的公钥S进行替换成自己的公钥M,然后在发送给客户端
- 此时客户端就能够拿到一个公钥,但是此时是不知道这个公钥是被修改过的了
- 接着将自己的密钥C+得到的公钥M生成密文,然后发送回服务端
- 此时又会被中间人截获,然后就会将这个密文+自己的密钥M’进行解析得到客户端的对称密钥C
- 然后将曾经保存过的服务端公钥S+客户端对称密钥进行加密后返回给服务端
- 此时服务端就能够拿到报文,然后用自己的S’私钥进行解密得到客户端密钥C
- 这样双方就能够通过客户端密钥C进行通信的,但是此时中间人也有密钥C,那么中间人就能够窃听、修改数据了
6、引入证书:
上述场景的核心问题就是:中间人修改公钥后,客户端无法知道,双方不知道中间人的存在
所以引入证书就是解决客户端能够辨认公钥是否合法的问题
在使用HTTPS前,需要向CA机构申请一份证书,这个证书就相当于身份证,里面包含了申请者的信息,公钥信息等等,当客户端比如果浏览器向服务端发起请求后,服务端进行响应的是这个证书而不是公钥,当客户端(浏览器)得到请求后,就会得到这个证书,然后就可以在证书里面得到公钥信息了
证书申请流程:
可以把证书理解为一个结构化的字符串,只有证书合法的时候才会进行非对称加密,包含信息有:
- 证书颁发机构
- 证书有效期
- 公钥
- 申请者或者申请机构信息
- 签名
- …
申请证书
申请证书时需要在特定平台生成,会同时生成公钥和私钥。这对密钥对就是用来在网络通信中进行明文加密以及数字签名的
其中公钥会随着CSR文件,⼀起发给CA进行权威认证,私钥服务端自己保留,用来后续进行通信(其实主要就是用来交换对称密钥)
审核
CA机构进行审核,主要是审核证书中的信息
签发证书
当认证成功后就进行签发证书,这个证书是放在服务端中的
返回证书
当客户端请求服务端的公钥的时候,服务端将证书响应给客户端,然后客户端对证书进行验证,看看是否合法,如果合法就证明公钥是可信的,接着就可以进行密钥协商了
介绍证书:
什么是CSR
证书是CA机构通过你提供的企业信息或者个人信息生成的,而你需要向CA机构提供的企业信息就是CSR,包括公钥,申请者的信息等等
接下来了解了解合法的证书中有什么
证书有签名和明文信息的
明文信息是公开的,里面有签发机构,证书时间,域名,申请者,公钥等等,这个公钥是服务端生成的公钥,当客户端拿到了证书后就能够得到里面的公钥,也就能够相信这个公钥
但是为什么能够相信这个公钥呢?
这就是归功于数字签名的功劳了
数字签名:
数字签名的本质是为了防止明文信息被篡改
我们知道通过特定算法对任意长度的原始数据进行处理,最终生成一段固定长度、唯一对应原始数据的二进制或十六进制字符串,本质是为数据生成一份数字身份证,这是数据摘要
CA机构自己有一对密钥对,用来进行数据摘要的加密
那么我们将明文信息进行摘要生成一份数据摘要,然后将这个数据摘要进行CA机构所有的私钥进行加密,这样就形成了数字签名,然后数字签名和明文信息一起构成了证书
那么客户端是怎么进行通过证书进行验证的呢?
如下,当客户端拿到证书后将证书一分为二,分别是明文信息和数据签名,将明文信息进行hash算法,得到散列值1,然后将数据签名这是被加密后的,通过CA机构的公钥进行解密得到散列值2,最后判断这两个散列值是不是相等的
7、方案五-----非对称加密+对称加密+证书认证
回看我们的方案四,是能够保证数据通信的安全的,但是问题是在一开始中间人就进行了攻击,但是现在有了证书,那么就能够保证通信之前的密钥交换了
总的来说:
- 服务端首先生成自己的密钥对,然后将公钥,申请人信息等等作为CSR文件交给权威的CA机构进行申请
- 然后CA机构审核成功得到明文信息,然后将明文信息和CA机构特有的密钥对中的私钥进行加密,将公钥公布出去
- 之后将证书返回给服务端,这样服务端就有了证书
- 当客户端请求服务端的密钥的时候,服务端将证书响应给客户端,此时客户端就拿到了证书
- 然后将拿到的证书一分为二,得到明文信息和数据签名
- 接着对数据签名通过CA机构公钥的解密得到散列值
- 然后对明文信息进行相同的hash算法得到另一个散列值
- 最后对这两个散列值进行比对
周边问题?
那么上述流程有没有问题呢?
中间人有没有可能篡改证书?
篡改证书有两种情况:只修改明文信息,修改明文信息和数据签名(应该不会有人只修改数据签名吧)
当修改明文信息之后,客户端拿到证书后,进行散列值的修改发现不一样,就会知道明文信息被修改了,就不承认当前明文信息中的数据了
当修改明文信息和数据签名后,由于客户端进行数据签名的解密的时候用的是说颁发CA机构的公钥,然而中间人是不可能有CA机构的私钥的,无法对修改后的数据摘要进行加密形成数据签名,所以也就没法对篡改后的证书形成匹配的签名了
中间人有没有可能将整个证书换掉
中间人是无法制作假的证书的,因为中间人没有CA机构的私钥,所以中间人如果想换掉整个证书只有向CA机构申请真的证书然后进行掉包,这样确实能够将整个证书进行掉包,但是里面的明文数据就不一样了,比如说域名就不一样了,我们又知道域名是唯一的,那么客户端也是能够识别证书有没有被修改而识别出来的
为什么签名不是选择直接加密,而是要先 hash 形成摘要?
缩小签名密文的长度,加快数字签名的验证签名的运算速度