文章目录
- 🌴HTTPS协议是什么?
- 🎄运营商劫持事件
- 🌲HTTPS的工作过程
- 🌸对称加密
- 🌸非对称加密
- 🌸引入证书
- 🌸完整流程
- 🌳HTTPS加密总结
- ⭕总结
🌴HTTPS协议是什么?
HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层.
HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在传输过程中出现一些被篡改的情况,比如臭名昭著的“运营商劫持事件”
🎄运营商劫持事件
比如我们这里下载一个 天天动听
以下是未被劫持的效果, 点击下载按钮, 就会弹出天天动听的下载链接.
已被劫持的效果, 点击下载按钮, 就会弹出 QQ 浏览器的下载链接
由于我们通过⽹络传输的任何的数据包都会经过运营商的⽹络设备(路由器, 交换机等), 那么运营商的⽹
络设备就可以解析出你传输的数据内容, 并进⾏篡改.
点击 “下载按钮”, 其实就是在给服务器发送了⼀个 HTTP 请求, 获取到的 HTTP 响应其实就包含了该
APP 的下载链接. 运营商劫持之后, 就发现这个请求是要下载天天动听, 那么就⾃动的把交给⽤⼾的响应
给篡改成 “QQ浏览器” 的下载地址了.
思考下, 为啥运营商要进⾏劫持?
不⽌运营商可以劫持, 其他的 ⿊客 也可以⽤类似的⼿段进⾏劫持, 来窃取⽤⼾隐私信息, 或者篡改内容.
在互联⽹上, 明⽂传输是⽐较危险的事情!!!
HTTPS 就是在 HTTP 的基础上进⾏了加密, 进⼀步的来保证⽤⼾的信息安全
🌲HTTPS的工作过程
既然要保证数据安全, 就需要进行 “加密”.
网络传输中不再直接传输明文了, 而是加密之后的 “密文”.
加密的方式有很多, 但是整体可以分成两大类: 对称加密 和 非对称加密
🌸对称加密
对称加密其实就是通过同一个 “密钥” , 把明文加密成密文, 并且也能把密文解密成明文
一个简单加密示例如下:
⼀个简单的对称加密, 按位异或
假设 明⽂ a = 1234, 密钥 key = 8888
则加密 a ^ key 得到的密⽂ b 为 9834.
然后针对密⽂ 9834 再次进⾏运算 b ^ key, 得到的就是原来的明⽂ 1234.
(对于字符串的对称加密也是同理, 每⼀个字符都可以表⽰成⼀个数字)
当然, 按位异或只是最简单的对称加密. HTTPS 中并不是使⽤按位异或.
当然, 按位异或只是最简单的对称加密. HTTPS 中并不是使用按位异或.
具体如何使用我们这里不做深究,这里重点在于理解原理
引入加密后,引入对称加密之后, 即使数据被截获, 由于黑客不知道密钥是啥, 因此就无法进行解密, 也就不知道请求的真实内容是啥了.
但事情没这么简单. 服务器同一时刻其实是给很多客户端提供服务的. 这么多客户端, 每个人用的秘钥都必须是不同的(如果是相同那密钥就太容易扩散了, 黑客就也能拿到了). 因此服务器就需要维护每个客户端和每个密钥之间的关联关系, 这也是个很麻烦的事情~
⽐较理想的做法, 就是能在客⼾端和服务器建⽴连接的时候, 双⽅协商确定这次的密钥是啥~
但是如果直接把密钥明⽂传输, 那么⿊客也就能获得密钥了~~ 此时后续的加密操作就形同虚设了.
**因此密钥的传输也必须加密传输! **
但是要想对密钥进⾏对称加密, 就仍然需要先协商确定⼀个 “密钥的密钥”. 这就成了 “先有鸡还是先有
蛋” 的问题了. 此时密钥的传输再⽤对称加密就⾏不通了.
就需要引⼊非对称加密.
🌸非对称加密
非对称加密要用到两个密钥, 一个叫做 “公钥”, 一个叫做 “私钥”.
公钥和私钥是配对的. 最大的缺点就是运算速度非常慢,比对称加密要慢很多.
- 通过公钥对明文加密, 变成密文
- 通过私钥对密文解密, 变成明文
也可以反着用
- 通过私钥对明文加密, 变成密文
- 通过公钥对密文解密, 变成明文
这里的加密过程就相当于
我有一把钥匙(私钥)和一把(锁),我把锁给你,你把想要给我的数据放在一个盒子里面,并用这把锁锁上,这时候这个箱子只有我手上的钥匙可以打开
公钥每个人都知道,是公共的,私钥只有服务器知道
大致过程如下:
• 客⼾端在本地⽣成对称密钥, 通过公钥加密, 发送给服务器.
• 由于中间的⽹络设备没有私钥, 即使截获了数据, 也⽆法还原出内部的原⽂, 也就⽆法获取到对称密
钥
• 服务器通过私钥解密, 还原出客⼾端发送的对称密钥. 并且使⽤这个对称密钥加密给客⼾端返回的响
应数据.
• 后续客⼾端和服务器的通信都只⽤对称加密即可. 由于该密钥只有客⼾端和服务器两个主机知道, 其
他主机/设备不知道密钥即使截获数据也没有意义
由于对称加密的效率⽐⾮对称加密⾼很多, 因此只是在开始阶段协商密钥的时候使⽤⾮对称加密, 后续
的传输仍然使⽤对称加密.
那么接下来问题⼜来了:
• 客⼾端如何获取到公钥?
• 客⼾端如何确定这个公钥不是⿊客伪造的?
理解中间人攻击
我有一把钥匙(私钥)和一把(锁),我需要不把锁给你,但是此时我可能不太方便,就让张三转交给你
这时候张三动了歪脑筋,他自己准备一把新的钥匙(黑客自己的私钥)和一把新的锁(黑客自己的公钥)。
然后他把自己准备的锁交给你,这时候你将东西放入盒子加上锁后交给张三
这时候张三就可以拿自己准备钥匙打开锁,把里面的东西进行修改后,再用我准备交给你的锁锁上后,再教给我
这样一来,我们两个双方都以为天衣无缝,结果早就已经被张三掌控
🌸引入证书
在客户端和服务器刚一建立连接的时候, 服务器给客户端返回一个 证书.
这个证书包含了刚才的公钥, 也包含了网站的身份信息.
这个证书就好比人的身份证, 作为这个网站的身份标识. 搭建一个 HTTPS 网站要在CA机构先申请一个证书. (类似于去公安局办个身份证)
这个 证书 可以理解成是一个结构化的字符串, 里面包含了以下信息:
- 证书发布机构
- 证书有效期
- 公钥
- 证书所有者
- 签名
当客户端获取到这个证书之后, 会对证书进行校验(防止证书是伪造的).
- 判定证书的有效期是否过期
- 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).
- 验证证书是否被篡改: 从系统中拿到该证书发布机构的公钥, 对签名解密, 得到一个 hash 值(称为数据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对比 hash1 和 hash2 是否相等.如果相等, 则说明证书是没有被篡改过的
那么问题来了,这个证书黑客是否可以伪造呢?
首先我们需要理解数据摘要 / 签名
针对一段数据(比如一个字符串), 也可以通过一些特定的算法, 对这个字符串生成一个 “签名”. 并保证不同的数据, 生成的 “签名” 差别很大. 这样使用这样的签名就可以一定程度的区分不同的数据.
常见的生成签名的算法有: MD5 和 SHA 系列
以 MD5 为例, 我们不需要研究具体的计算签名的过程, 只需要了解 MD5 的特点:
-
定长: 无论多长的字符串, 计算出来的 MD5 值都是固定长度 (16字节版本或者32字节版本)
-
分散: 源字符串只要改变一点点, 最终得到的 MD5 值都会差别很大.
-
不可逆: 通过源字符串生成 MD5 很容易, 但是通过 MD5 还原成原串理论上是不可能的.
正因为 MD5 有这样的特性, 我们可以认为如果两个字符串的 MD5 值相同, 则认为这两个字符串相同
接下来我们就可以理解判定证书篡改的过程: (这个过程就好比判定这个身份证是不是伪造的身份证)
-
假设我们的证书只是一个简单的字符串 hello, 对这个字符串计算hash值(比如md5), 结果为BC4B2A76B9719D91
-
如果 hello 中有任意的字符被篡改了, 比如变成了 hella, 那么计算的 md5 值就会变化很大.BDBD6F9CF51F2FD8
-
然后我们可以把这个字符串 hello 和 哈希值 BC4B2A76B9719D91 从服务器返回给客户端, 此时
-
客户端如何验证 hello 是否是被篡改过?
-
那么就只要计算 hello 的哈希值, 看看是不是 BC4B2A76B9719D91 即可
但是还有个问题, 如果黑客把 hello 篡改了, 同时也把哈希值重新计算下, 客户端就分辨不出来了呀
这个哈希值在服务器端通过另外一个私钥加密(这个私钥是申请证书的时候, 证书发布机构给服务器的, 不是客户端和服务器传输对称密钥的私钥).
然后客户端通过操作系统里已经存的了的证书发布机构的公钥进行解密, 还原出原始的哈希值, 再进行校验.
就相当于,黑客劫持了进行解密之后,进行篡改了,没有服务器的私钥进行加密,当他把这个数据传输给客户端时,客户端解密后,就会发现内容被人篡改了。
🌸完整流程
🌳HTTPS加密总结
HTTPS 工作过程中涉及到的密钥有三组
-
第一组(非对称加密): 用于校验证书是否被篡改. 服务器持有私钥(私钥在注册证书时获得), 客户端持有公钥(操作系统包含了可信任的 CA 认证机构有哪些, 同时持有对应的公钥). 服务器使用这个私钥对证书的签名进行加密. 客户端通过这个公钥解密获取到证书的签名, 从而校验证书内容是否是篡改过.
-
第二组(非对称加密): 用于协商生成对称加密的密钥. 服务器生成这组 私钥-公钥 对, 然后通过证书把公钥传递给客户端. 然后客户端用这个公钥给生成的对称加密的密钥加密, 传输给服务器, 服务器通过私钥解密获取到对称加密密钥.
-
第三组(对称加密): 客户端和服务器后续传输的数据都通过这个对称密钥加密解密
其实一切的关键都是围绕这个对称加密的密钥. 其他的机制都是辅助这个密钥工作的.
-
第一组非对称加密的密钥是为了让客户端拿到第二组非对称加密的公钥
-
第二组非对称加密的密钥是为了让客户端把这个对称密钥传给服务器.
⭕总结
感谢大家的阅读,希望得到大家的批评指正,和大家一起进步,与君共勉!