目录
MITM攻击(Man-in-the-Middle Attack)
下面,我们自主思考如何解决http协议的明文传输(也就是如何对它进行加密)
- 从而可以深入理解主流的https方案的设计想法
如何对http协议的数据进行加密
只使用对称加密
如果只使用对称加密
- 那么通信双方建立好协议,使用同一个秘钥对数据进行处理,各自都存放秘钥
但是,秘钥存放在客户端,本身就不是一个安全的事情,cookie文件能被盗取,自然秘钥也可以
- 如果秘钥被拿走,黑客就可以自行对数据解密了
并且,面对数量庞大的客户端,服务器要维护很多很多的秘钥,挺不容易的
- 如果只设置一种秘钥,那一个丢失,其他就全完蛋了
不仅如此,要是服务器想要修改秘钥,如何让全部的客户端都配合呢?
迂回措施
要是采取迂回的措施,客户端在发送正式请求前,先请求服务器发送秘钥过来,然后再加密
- 这同样非常离谱,在秘钥被发回客户端的过程,依然可以被黑客截胡
如果说对秘钥进行加密呢?
- 这就变成了鸡生蛋,蛋生鸡的问题了 -- 如何进行加密呢?对称加密吗?这就又回到刚开始了
所以,只使用对称加密是不合理的
只使用非对称加密
请求过程
如果只使用非对称加密
- 客户端访问服务器时,会先发送请求,表示使用的是https协议
- 那么服务器也会使用https协议,并且在响应中携带公钥
公钥即使在传输过程被盗取也没事
- 因为公钥本来就是公开的,是用来加密的
当客户端拿到公钥并对数据进行加密处理,然后发给服务器
- 服务器收到加密数据,使用内部对应的私钥进行解密,就可以拿到有效数据
所以,传送请求这一过程是安全的
响应过程
但是,当服务器处理完请求后给客户端发送响应时,数据要不要加密?
- 要的
- 但只能使用私钥加密 (因为如果用公钥的话,客户端那边没法解密,客户端只持有公钥)
那么,响应数据是可以被黑客解密的
- 因为黑客可以拿到公钥
所以,传送响应的过程是不安全的
使用两种非对称加密机制
既然请求过程是安全的,那让响应过程也使用那套模式呢(也就是让客户端也持有私钥)
- 也就是,客户端和服务器各拥有一套非对称加密机制
也就是进行下面的过程:
交换公钥的目的
- 让对方拥有自己的加密方法
- 这样可以保证收到的数据是只有自己才能解密的
但是,本身非对称加密的速度就慢
- 用以上方法,通信全程都使用的是非对称,太影响效率了
而且,虽然看起来很有道理,但实际上还是存在安全问题
- 将会在下面的中间人攻击那里介绍,看完那个再回过头看这里,就可以看出确实存在问题(在于交换公钥的过程)
所以,左思右想,只能将二者结合在一起使用了
对称+非对称加密
思路
首先,先按照只使用非对称加密的逻辑
- 服务器拥有非对称公钥和私钥,服务器发给客户端公钥
如果按照原来的,这里就直接加密通信了
- 但这里不同,客户端先形成一个对称密钥
- 然后对称密钥+非对称公钥->加密数据 (相当于使用[非对称加密的公钥]对[对称密钥]进行加密)
将这串数据发送给服务器
- 即使被截胡,没有非对称私钥,也是无法解密的
服务器收到加密数据后
- 加密数据+非对称私钥->对称密钥 (相当于使用[非对称加密的私钥]对[加密数据]进行解密)
- 所以,服务器就可以拿到客户端生成的对称密钥
然后再根据这个对称密钥,双方直接进行通信
- 因为通信过程中并不涉及秘钥的传输,自然也不会泄漏
图解
虽然看起来很完美了,但实际上还是存在安全问题
MITM攻击(Man-in-the-Middle Attack)
如果这个黑客一早就在监控请求呢?
过程
因为某种原因,一开始,客户端和服务器之间的通信就需要经过中间人
- 连接钓鱼wifi啦,中病毒啦什么的
那么,服务器返回给客户端的非对称公钥就会先发送给中间人
- 注意,中间人会自带一套非对称加密机制
- 所以它会将[响应里的公钥]替换成自己的,并且把原来的保存下来
当客户端将[自己形成的对称密钥]使用[中间人的公钥]加密后,发送给服务器
- 客户端以为收到的就是服务器的公钥,并且发送的对象也是服务器
- 但实际收发对象却插入了一个中间人
- 所以,这个中间人会收到来自客户端的请求,并且使用自己的私钥解密出[客户端形成的对称密钥]
那么,之后双方的通信数据对于中间设备来说相当于是透明的了
- 因为对称密钥已经被拿到辣
接着说
- 当中间人解密出对称密钥后,又用保存下来的[原非对称公钥]加密[对称密钥],发送给服务器 (这段数据确实符合服务器的预期)
- 然后通信双方就以为已经建立好了安全协议,但可惜秘钥早就已经被截获了
图解
介绍
中间人攻击(Man-in-the-Middle Attack,简称MITM攻击)是一种常见的网络安全威胁
- 其基本原理是攻击者通过操纵通信过程中的数据流量,使得通信的两端认为他们正在直接与对方通信,但实际上所有的数据都经过了攻击者的拦截和监控
- 攻击者可以窃取、篡改或者注入恶意内容
解决
如何解决上述问题呢?
- 首先明确问题究竟出在哪里 -- 就是因为客户端收到了不属于服务器的公钥,却无法分辨
- 一切的问题都出在客户端直接使用了收到的公钥
所以,解决问题的方式就是 -- 保证公钥的合法性
证书
引入
验证公钥的合法性
- 其实也可以是验证发送者的身份
类比现实,其他人怎么知道我们的身份呢?
- 通过身份证/学生证
- 而这些证件都是由第三方的众所周知的权威机构颁发的
而在网络里
- 我们每个网站都需要向CA机构申请CA认证
- 而它授权过的二级机构,也是可信的
申请证书的流程
生成公钥/私钥对
其实就是我们在上面思路里的服务器内部的非对称公钥和私钥(也就是申请者的秘钥)
确认申请信息
域名
- 每个网站都有自己的域名,并且不能重复
申请者
- 法人个人信息/公司主体信息
公钥
- 刚刚生成的非对称公钥
- (注意,私钥一定是只被服务器持有的,一定不能暴露)
生成请求文件
根据申请信息,生成一个请求文件,推送给CA机构
- .csr后缀
在线生成请求文件的网站:
可以看到图中并没有让我们填写公钥
- 因为公钥不需要我们填写,它会自动生成
填写完请求信息后
- 会为我们提供私钥和证书请求文件的下载链接
- 而公钥已经自动为我们在证书里填写了
签发证书
证书格式
证书由签名+明文信息构成
在明文信息中
- 公钥是最重要的(当然,其他信息也很重要,等会就会说)
- 因为客户端就是要根据证书里的公钥,来验证实际收到公钥的合法性
签名我们先按下不表,等会就会介绍
验证证书
客户端要验证公钥的合法性
- 首先要确保证书的合法性 -- 不仅是要符合要求,也要保证它没有被篡改
确保符合要求
首先:
- 要判断证书的有效期是否过期
- 以及发布机构是否受信任 (os中会内置受信任的证书发布机构,包括CA承认的二级机构)
查看受信任的证书发布机构
在浏览器中的设置中,可以找到管理证书
不仅如此,还可以查看证书的详细信息:
除此之外,还需要看看证书里填写的域名是否是我们实际要访问的
- 在下面的第四种解决http加密的方法里会介绍,为什么要验证域名
确保没有被篡改
如何知道证书确实是权威机构颁发的,且没有被篡改过呢?
- 也就到了证书里签名的用武之地了
- 也就是通过验证签名,来知道证书是否被篡改
这里证书中的签名 = 我们在数据摘要里提到的,数字摘要经过非对称加密后->数字签名
先来了解一下数字签名
数字签名
介绍
数字签名是一种用于验证数字文档或数据完整性和来源的技术
- 它基于公钥加密系统,使用发送者的私钥对数字摘要进行加密生成数字签名,接收者可以使用发送者的公钥解密签名以验证数据的真实性和完整性
- 这种技术通常用于确保数字文件在传输过程中不被篡改,并且可以确定文件的真实来源
简单来说,就是数字摘要 -非对称私钥加密->数字签名
具有数字签名的数据的形成过程
- 我们将明文形成数据摘要
- 并对它进行非对称加密形成签名
- 再把明文和签名拼在一块,得到具有数字签名的数据
为什么要形成数据摘要?
- 为了缩小明文的长度,加快验证签名的运算速度
- 因为明文的长度是不确定的,而数据摘要的长度是固定的
- 加密数据摘要可以使加密解密操作的速度比较稳定,不会出现效率方面的振荡
验证数字签名
将具有数字签名的数据拆成两部分 -- 明文数据+签名
- 明文数据 -散列函数-> 散列值(也就是使用哈希算法得到数字摘要)
- 签名 -非对称公钥解密-> 散列值(还原回数字摘要)
通过对比两者的散列值
- 如果一致,则该数据没有被篡改过,则数字签名有效
- (还记得吗,我们的数字摘要是,数据只要有一点点的区别,生成的摘要就完全不同)
回到证书这里
CA证书的形成过程
以CA机构的视角来重新看数字签名的形成过程
介绍
过程
- 我们把用户(也就是公司人员)提交上来的数据(也就是请求文件)经过散列函数->散列值(数字摘要)
- 使用CA机构内部的私钥对其加密,形成签名(所以,图里的签名者指的是CA机构)
- 然后把数据+签名->证书,就完成了签发证书的过程
最后把证书交给服务器
- 之后,就进入通信流程了
这个证书不是那种需要挂在墙上的(什么营业执照啊那种)
- 这个是需要安装在服务器里的
以上都属于建站的准备工作
- 一段时间内只需要做一次(因为CA证书是有期限的,到期了需要重新申请)
介绍完证书后,我们就可以拿出第五套加密http数据的方案了
- 之前不是说客户端无法甄别公钥吗,证书就帮我们补足了这一部分
非对称加密+对称加密+证书认证
思路
当客户端想要访问服务器时,服务器直接返回证书
- 证书里包含服务器的非对称公钥
- 相当于用证书替代了之前传的非对称公钥
但是,先不着急开始加密
- 我们得先认证证书
- 以免跟上一个方案一样,加密了中间人的公钥还不自知
认证证书
步骤
根据上面介绍的验证数字签名的步骤
- 我们需要先将收到的证书拆分成两部分,实际的明文信息+数字签名
- 然后将实际的明文信息 -CA机构内使用的哈希算法-> 数据摘要
- 数字签名 -CA机构的非对称公钥-> 解密出数据摘要(也就是原证书的明文信息转化来的数据摘要)
小细节
如果成功解密
- 则说明这个数字签名正是使用了CA机构的非对称私钥进行加密的
因为客户端只认CA机构的公钥,而私钥只有CA机构内部拥有
- 所以,可以排除中间人篡改数字签名的情况,因为一旦修改了,客户端是解密不了的
- 所以,通过签名解密出的[数据摘要]是绝对有效的,它就可以作为对比的基准
这也就是为什么数字摘要要进行非对称加密的原因
- 就是为了防止中间人将篡改后的明文信息,重新使用相同的哈希算法转换为数字摘要
- 如果不加密,则会鱼目混珠
- 如果使用对称加密,那客户端一定拥有对称密钥,万一被中间人盗取就完了
- 但如果使用的是CA机构的私钥,则中间人不可能把转换后的数字摘要加密成签名 -- 那么两个数字摘要一定不相同,也就甄别出来了
客户端哪来的CA机构的公钥呢?
- 客户端会内置很多权威CA机构的公钥
后续
进行比对
如果证书明文信息->摘要 和 通过签名解密出的 数据摘要 相同
- 则说明信息未被篡改
- 如果未被篡改,则说明该证书有效 -> 公钥有效
如果不同,则说明证书内存放的公钥已经被中间人修改,也就不进行下去了
形成对称密钥
认证完成后,还是原来的
- 客户端自己形成对称密钥,然后公钥加密它
- 然后把加密信息交给服务器
然后这俩就建立好协议了,可以开始使用对称密钥通信了
总结
其实重点就是用[只有CA机构拥有的私钥]来加密数据,那么就一定会有一份数据是绝对安全的
所以,明文/签名被修改,我们都是可以甄别出来的
- 明文修改,通过比对签名知道
- 签名修改,中间人没有私钥无法加密,客户端也就解密不出来
中间人替换整个证书
引入
上面说了,修改二者中任何一方都可以被客户端甄别出来
- 那要是黑客发了狠,自己申请一个证书替换掉服务器的响应呢?
介绍
那中间人就得提交真的请求文件信息
- 因为还得经过CA机构审核
那就会导致,两个证书的域名不同(不会有相同的域名)
- 所以,客户端可以通过检查域名来规避上述情况
应用
听起来似乎挺傻的,但还真的会有人这么干:
比如一些民间网站仿照权威网址的风格+域名
- 会有人没注意就访问了假网站,从而获取到信息
而这种我们就没法了,只能让公安机关去处理
- 刚好证书里面有申请者等等信息,相当于实名制了,直接带走
总结
虽然https协议工作工程中涉及到三组密钥,但核心还是对称密钥
其他两组是用来辅助的
- 一组是服务器的非对称加密,公钥用来加密对称密钥
- 一组来源于第三方机构的非对称加密,用于保证非对称公钥是可信的
我们介绍了一大堆的东西
- 其实本质上就是在解决如何保证公钥合法性的问题 -- 证书
- 我们必须引入可信的第三方来帮助我们甄别
我们就这样不断探讨,最终把https协议引了出来
https
介绍
HTTPS是一种通过加密通道传输数据的网络协议,用于在Web浏览器和网站服务器之间进行安全通信
- 它通过使用SSL(安全套接字层)或TLS(传输层安全)协议来保护数据的传输安全性和完整性
- 相较于普通的HTTP,HTTPS提供了更高的安全性,因为它使用了加密来保护数据免受窃听和篡改 ,这种加密通常使用SSL证书来实现,证书由可信任的第三方颁发机构签发,用于验证网站身份
总之它可以有效防止中间人的攻击
问题
引入
但世界上没有绝对的安全
上面我们介绍的中间人,针对的对象都是客户端
- 它劫持数据想要修改公钥,无非就是想获取客户端和服务器之间通信的数据
- 比如:客户端的用户信息/隐私信息等等,都是针对客户端
- 当我们引入第三方后,就可以帮助客户端甄别并避免数据泄漏
当然也不排除想要针对服务器
介绍
如果客户端本身就是黑客呢?
比如黑客做了个软件充当浏览器,把浏览器内置的东西也都给软件放了一份,然后和服务器建立协议
- 这样,由于对称密钥也是在软件内部生成的,所以该软件就可以拿到和服务器通信的数据了
- 进而可能就可以分析出服务器的一些信息
即使是https,也防不住这样的情况
- 所以可能需要引入新的加密手段
- 或是在服务器端实施严格的信任链验证,确保只有经过认证和授权的客户端才能建立安全连接
- 定期对客户端软件进行安全审计,确保其不受恶意代码或后门的影响