HTTPS协议
HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层.
HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在传输过程中出现一些被篡改的情况.
【运营商劫持问题】
下载一个 天天动听 未被劫持的效果, 点击下载按钮, 就会弹出天天动听的下载链接
已被劫持的效果, 点击下载按钮, 就会弹出 QQ 浏览器的下载链接由于我们通过网络传输的任何数据包都会经过运营商的网络设备(路由器,交换机等),因此运营商的网络设备就可以解析出传输数据的内容,并进行篡改
点击 “下载按钮”, 其实就是在给服务器发送了一个 HTTP 请求, 获取到的 HTTP 响应其实就包含了该 APP 的下载链接. 运营商劫持之后, 就发现这个请求是要下载天天动听, 那么就自动的把交给用户的响应给篡改成 “QQ浏览器” 的下载地址了
不止运营商可以劫持, 其他的 黑客 也可以用类似的手段进行劫持, 来窃取用户隐私信息, 或者篡改内容
在互联网上, 明文传输是比较危险的事情!!!
加密的介绍
加密就是把 明文 (要传输的信息)进行一系列变换, 生成 密文 .
解密就是把 密文 再进行一系列变换, 还原成 明文 .
在这个加密和解密的过程中, 往往需要一个或者多个中间的数据, 辅助进行这个过程, 这样的数据称为 密钥
HTTPS的工作过程
网络传输中不再直接传输明文了, 而是加密之后的 “密文”.
加密的方式有很多, 但是整体可以分成两大类: 对称加密 和 非对称加密
对称加密
对称加密其实就是通过同一个 “密钥” , 把明文加密成密文, 并且也能把密文解密成明文.
引入对称加密之后, 即使数据被截获, 由于黑客不知道密钥是啥, 因此就无法进行解密, 也就不知道请求的真实内容是啥了.
但事情没这么简单. 服务器同一时刻其实是给很多客户端提供服务的. 这么多客户端, 每个人用的密钥都必须是不同的(如果是相同那密钥就太容易扩散了, 黑客就也能拿到了). 因此服务器就需要维护每个客户端和每个密钥之间的关联关系, 这也是个很麻烦的事情
比较理想的做法, 就是能在客户端和服务器建立连接的时候, 双方协商确定这次的密钥是啥,每个客户端在和服务器建立连接的时候,自己生成一个密钥,每个客户端生成的密钥都不相同
但是如果直接把密钥明文传输, 那么黑客也就能获得密钥了,此时后续的加密操作就形同虚设了.
但是要想对密钥进行对称加密, 就仍然需要先协商确定一个 “密钥的密钥”. 这就陷入了一个死循环了. 此时密钥的传输再用对称加密就行不通了.
就需要引入非对称加密.
非对称加密
非对称加密要用到两个密钥, 一个叫做 “公钥”, 一个叫做 “私钥”.
公钥和私钥是配对的. 最大的缺点就是运算速度非常慢,比对称加密要慢很多.
- 通过公钥对明文加密, 变成密文
- 通过私钥对密文解密, 变成明文
也可以
- 通过私钥对明文加密, 变成密文
- 通过公钥对密文解密,变成明文
非对称密钥的公钥和私钥有服务器生成,其中公钥会被服务器公布出来,私钥只有服务器自己知道不会进行公布
- 服务器生成一对公钥和私钥,自己保留私钥,将公钥公布出去,客户端也就能拿到公钥了
- 客户端在本地生成对称密钥, 通过公钥加密, 把加密之后的密文通过网路来进行传输,发送给服务器
- 由于中间的网络设备没有私钥, 即使截获了数据, 也无法还原出内部的原文, 也就无法获取到对称密钥
- 服务器通过私钥解密, 还原出客户端发送的对称密钥. 并且使用这个对称密钥加密给客户端返回的响应数据.
- 后续客户端和服务器的通信都只用对称加密即可. 由于该密钥只有客户端和服务器两个主机知道, 其他主机/设备不知道密钥即使截获数据也没有意义.
既然非对称加密这么香,为什么还要使用对称加密呢?
非对称加密的加密和解密的开销,是非常大的,不如对称加密轻量
但上述过程也并不是无懈可击的,黑客仍然有办法对上述加密方案进行反制?
中间人攻击
- 客户端首先向服务器询问公钥
- 服务器生成一对公钥pub1和私钥pri1之后,会将公钥返回
- 黑客在中间收到服务器返回给客户端的公钥pub1时,黑客自己也会生成一对公钥pub2和私钥pri2,并将pub2返回给客户端
- 客户端收到pub2后,使用pub2对 对称密钥(88888)进行加密,加密后传输给服务器
- 黑客使用pri2对 使用pub2加密的密文进行解密,得到对称密钥是88888,然后使用pub1对88888进行加密后传输给服务器
- 服务器使用pri1对使用pub1加密的密文解密,得到对称密钥是88888,于是后续的服务器与客户端之间的数据传输就都是用88888作为密钥
- 但由于黑客悄无声息的拿到了对称密钥,因此后续的加密也就形同虚设
为了解决中间人攻击的问题就引入了证书
破解中间人攻击的关键,就得让客户端能够验证,当前这里的公钥是否是来自于真实的服务器
在客户端和服务器刚一建立连接的时候, 服务器给客户端返回一个 证书.
这个证书包含了刚才的公钥, 也包含了网站的身份信息.这个证书就好比人的身份证, 作为这个网站的身份标识. 搭建一个 HTTPS 网站要在CA机构先申请
一个证书. (类似于去公安局办个身份证).
- 这个 证书 可以理解成是一个结构化的字符串, 里面包含了以下信息:证书发布机构、证书有效期、公钥、证书所有者和签名等
- 当客户端获取到这个证书之后, 会对证书进行校验(防止证书是伪造的),判断证书的有效期,判断证书的发布机构是否受信任,判断证书是否被篡改(从系统中拿到该证书发布机构的公钥, 对签名解密, 得到一个 hash 值(称为数据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对比 hash1 和 hash2 是否相等. 如果相等, 则说明证书是没有被篡改过的.)
- 如果证书中的内容被篡改了,或者内容对不上(域名),浏览器就会弹窗提示
【理解证书被篡改的过程】
假设我们的证书只是一个简单的字符串 hello, 对这个字符串计算hash值(比如md5), 结果为BC4B2A76B9719D91 如果 hello 中有任意的字符被篡改了, 比如变成了 hella, 那么计算的 md5 值就会变化很大. BDBD6F9CF51F2FD8
然后我们可以把这个字符串 hello 和 哈希值 BC4B2A76B9719D91 从服务器返回给客户端,
此时客户端如何验证 hello 是否是被篡改过? 那么就只要计算 hello 的哈希值, 看看是不是 BC4B2A76B9719D91 即可
但是还有个问题, 如果黑客把 hello 篡改了, 同时也把哈希值重新计算下, 客户端就分辨不出来了呀.
所以被传输的哈希值不能传输明文, 需要传输密文. 这个哈希值在服务器端通过另外一个私钥加密(这个私钥是申请证书的时候,
证书发布机构给服务器的, 不是客户端和服务器传输对称密钥的私钥). 然后客户端通过操作系统里已经存的了的证书发布机构的公钥进行解密,
还原出原始的哈希值, 再进行校验
【申请证书的完整过程】