之前的文章中, 已经分析介绍过了HTTP
协议. HTTP
协议在网络中是以明文的形式传输的. 无论是GET
还是POST
方法都是不安全的.
为什么不安全呢? 因为:
-
HTTP
协议以明文的形式传输数据, 缺乏对信息的保护.如果在网络中传输数据以明文的形式传输, 网络中的任何人都可以轻松的获取数据中携带的敏感信息. 信息太容易泄露了
其次, 由于对信息没有保护措施. 任何人也都有可能篡改发送的信息.
想象一下, 如果你在和喜欢的人 在网上表白的时候, 有人把你发送的消息在网络中改了… 😱😱😱
由于HTTP
的不安全, 所以才出现了HTTPS
协议.
HTTPS
什么是HTTPS
HTTPS
协议也是一种应用层的协议.
按照TPC/IP
四层协议模型来看:
HTTP
和HTTPS
不同的是:
使用HTTPS
协议传输数据, 数据会经过加密之后再进行传输. 这一层加密层就是SSL/TLS
两个加密协议.
HTTPS
就是通过在HTTP
协议之上添加SSL/TLS
加密层来实现的.
既然有加密, 那必然也存在解密. 即, 使用HTTPS
传输数据, 在应用层和传输层之间时:
什么是加密
官方一点介绍:
-
加密 就是 把 明文(需要传输的数据) 通过一系列的转换, 生成 密文
比如要传输
123
, 通过把123
+456
得到579
(当然不可能这么简单) -
解密 就是 把 密文 再通过一系列的转换, 生成原本的 明文
579
-456
得到123
-
在 加密和解密的过程中, 往往需要一个或者多个中间的数据, 辅助进行这个过程, 这样的数据称为 密钥. 上面那个再简单不过的例子,
456
就是密钥
在举一个例子:
不知道大家有没有看过《剑来》这本小说. 这本小说前两卷有一段剧情是这样的: 陈平安(主角)在护送一群孩子去远方的一个书院求学. 但在路上发生了一件事, 队伍中 在镇子上稍有名望的家里的小姐收到了一些家书. 其中一封家书实际不是给这位小姐看的, 而是给身边的丫鬟看的. 那封家书洋洋洒洒几千字, 但只有那几个字使用楷书写的: “大骊柱国姓氏,
陈
氏嫡长孙,杀
马贼,太平
火,报平安
,得诰命
”, 用楷书写的7个字正是:杀陈平安得诰命
这就算是一种加密. 而密钥 则是懂楷书
为什么要加密
不知道以前大家 在网上下载东西的时候 有没有遇到过这样一种情况, 明明点的是一个软件的下载按钮, 但真正下载的确实另外一个软件. 不是现在那种 用一个假的下载按钮迷惑你, 而是点击真的下载按钮, 下载的却是其他软件.
这实际上是一种 运营商劫持, 下载软件时发生的多是 HTTP
劫持
发生这种情况的原因实际上是:
我们通过网络 传输的任何数据, 都会经过运营商的一系列网络设备(路由器、交换机等)传输.
使用HTTP
协议以明文的形式传输数据. 在下载软件的时候, 如果运营商发现 服务器响应回来的数据是某个软件(可能是特定的软件)的下载链接, 那运营商可能就会劫持此响应, 然后把响应数据设置为另外一个软件的下载链接. 然后用户下载的就是其他软件
像这样 信息在传输过程中被劫持,传输的内容完全暴露. 劫持者还可以篡改传输的信息且不被双方察觉
这实际是 中间人攻击, 这种情况是很可怕的. 所以 才需要对传输的数据进行加密
中间人 泛指 在通信的两个节点之间插入自己的设备或程序,以窃取、篡改或监控通信数据的攻击者
于是在现在的网络中, 绝大多数的网页都是用HTTPS
协议来传输数据.
常见的加密方式
上面介绍了HTTPS
是什么, 加密是什么, 为什么加密.
那么, 加密常见的有什么方式呢?
1. 对称加密
上面介绍了三个概念, 明文 密文 和 密钥.
在对称加密是 只用一个密钥进行加密或解密的加密 方式, 即 单密钥加密. 明文可以通过此密钥加密成为密文, 密文也可以通过此密钥解密成为明文
使用对称加密时, 通信双方保存的密钥是同一个密钥.
对称加密的特点是:
- 算法公开
- 计算量小
- 加密速度快
- 加密效率高
常见的对称加密算法有: DES
、3DES
、AES
、TDEA
、Blowfish
、RC2
等
举个简单的对称加密的例子: 按位异或
设 明文
a = 1234
, 密钥key = 8888
加密
a ^ key
得到的密文b = 9834
然后针对密文
9834
再次进行运算b ^ key
, 得到的就是原来的明文1234
2. 非对称加密
非对称加密 需要使用 两个密钥. 一个称为 公开密钥, 简称公钥 可以被任意人拥有 是公开的, 另一个则称为 私有密钥, 简称私钥 只自己拥有 不能公开
非对称加密中, 明文 可以分别 通过公钥 或 私钥 加密 生成密文, 对应的 密文 也需要分别 通过密钥 和 公钥 解密 还原明文.
但是, 如果明文通过 公钥加密, 那么生成的密文就只能通过 私钥解密
相反的 如果明文通过 私钥加密, 那么生成的密文就只能通过 公钥解密
可以将 公钥与私钥之间的关系 看作 互为钥匙 互为锁. 但是, 公钥是可以公开的, 私钥是不能公开的.
非对称加密最大的缺点就是: 运算速度慢, 比对称加密的运算速度要慢得多.
非对称加密的特点: 算法强度复杂、安全性依赖于算法与密钥
无论是对称加密或是非对称加密还是其他加密, 唯一的目的就是 防止中间人窃取或篡改数据, 使数据在网络中更加安全的传输
数据指纹(数据摘要)**
数据指纹(数据摘要) 的基本原理是 利用哈希函数对数据进行运算, 生成一串 固定大小的长字符串.
这里的固定长度, 是指所有通过同意算法计算出的数据指纹都是同一固定长度的.
数字指纹并不是一种加密机制, 因为只能通过数据计算出相应的字符串, 但是不能通过字符串反向还原出原数据.
数据指纹 可以用来 判断数据有没有被窜改. 因为一般情况下, 只要原数据有一丁点的改动, 通过哈希函数运算出来的结果相差就会非常的大.
常见的计算数据指纹的算法: MD5(16字节)
SHA1(20字节)
SHA256(32字节)
SHA512(64字节)
数据指纹有非常多的应用场景. 比如:
平常向网盘 上传资源的时候, 有些资源是可以秒传的. 为什么可以秒传呢? 实际就是因为 你上传的资源 其实已经在网盘的服务器中存储着了(可能别人上传过). 此时, 就不需要进行上传, 直接记录并链接就可以了
还有就是, 注册账号时, 你的密码可能并不会直接以明文密码的形式存储在服务器中. 而是存储密码的数据指纹. 因为登陆账号时, 并不需要通过原数据进行对比, 可以直接根据数据指纹来对比 是否与服务器中的密码相符合.
当然, 不仅仅只是简单的使用数据指纹. 一定还有其他的加密方式一起使用.
数字签名
数字签名是基于非对称加密的生成的, 是对数据指纹的加密生成的
使用HTTPS
协议的工作流程**
上面介绍了 两种加密方式以及相关的一些概念.
那么, HTTPS
究竟是用什么方式加密的呢? 是对称加密? 还是非对称加密?
其实都不是, 或者说都是. HTTPS
的加密方式是 先非对称加密之后再对称加密
关于为什么这样做, 就要分析一下各种加密方式的各种情况了:
1. 只用对称加密
对称加密是指 只是用单一密钥的加密方式.
那么, 只要通信双方(一般是客户端和服务器)都保存有此密钥, 并且不泄露 不破解的情况下, 双方的安全是可以保证的.
因为, 即使有中间人获取到了加密数据, 但不知道密钥是什么, 也是无法获取数据具体的内容的:
所以看起来, 对称加密是可行的.
但 并不是这么简单的.
服务器一般是负责服务多客户端的. 不同客户端与服务器之间的密钥必须是不同的, 所以 服务器需要维护好 各个客户端与对应密钥之间的联系, 以保证可以正常的提供服务.
这是非常麻烦的. 难道要提前给每个客户端分配好密钥吗, 这肯定是不现实的
比较理想的做法是, 在此次 客户端与服务器建立连接的时候, 双方协定此次通信的密钥:
但是如果这样做, 把中间人放哪里了?
所以, 在协商密钥的时候 密钥也是需要加密传输的
但是, 服务器还不知道密钥, 你客户端加密传输了 服务器怎么解密?
这就出现了一个经典的鸡生蛋蛋生鸡的问题
所以, 只用对称加密是行不通的
2. 只用单一的非对称加密
根据非对称加密的特点: 双密钥, 一个公钥 一个私钥. 即使公钥 明文传输也没有问题, 因为公钥是可以公开的.
所以如果使用非对称加密, 是不是可以这样协商密钥:
客户端先问服务器要公钥, 然后服务器以明文的方式把公钥给客户端. 在之后的通信中, 客户端使用公钥加密, 服务器使用私钥解密就可以了.
公钥加密需要使用私钥解密, 所以好像即使中间人获取了公钥, 也没法对客户端加密的数据进行解密:
如果中间人只知道公钥, 就没有安全问题吗?
如果使用公钥对数据加密, 解密这需要私钥. 中间人确实无法解密 客户端加密的数据.
但是, 中间人获取到公钥之后, 可以对 服务器使用私钥加密的数据 进行解密.
也就是说, 如果只用单一的非对称加密, 公钥加密发送的数据无法被中间人解密, 而使用私钥加密发送的数据 是可以被中间人解密获取的.
这样数据就又泄露了.
3. 双方均使用非对称加密
单一的非对称加密不行, 因为总有一方是拿着私钥进行加密的. 而中间人可以获取到公钥, 也就意味着中间人可以获取到以对应私钥加密的数据
如果是双方都是用非对称加密呢?
也就是说, 客户端拥有公钥A和私钥A’, 客户端将公钥A发给服务器, 让服务器响应数据时 用公钥A加密
而 服务器拥有公钥B和私钥B’, 服务器将公钥B发给客户端, 让客户端发送请求时 用公钥B加密
这样, 都是用公钥对向外发送的数据加密 的. 中间人即使获取了两个公钥, 也无法获取到数据内容:
但是, 这样做还有问题:
-
效率太低.
单一的非对称加密已经很慢了, 如果通信双方都是用非对称加密. 那就是慢上加慢
-
还是有安全问题的(暂不解释)
4. 非对称加密 + 对称加密
通信双方都 使用非对称加密的方法, 之后的每次加密解密都需要公钥加密 私钥解密, 效率太低.
那有没有办法提高效率呢?
答案是有的. 那就是 先非对称加密协商公钥, 再通过公钥 加密 对称密钥 将加密的密钥发送给私钥持有者.
然后使用私钥将加密的对称密钥解密出来, 之后的通信中都只使用对称加密的方式来进行加密.
也就是说, 只在协商阶段使用非对称加密, 之后的通信都使用对称加密, 这样效率就会快很多:
这样效率的问题解决了. 好像也不存在安全问题了吧.
如果, 客户端与服务器已经非对称加密协商完成了. 即使中间人获取了公钥, 后面的数据内容也就无法获取了
但是, 如果中间人在非对称加密协商未完成的时候, 获取到了公钥, 然后做了手脚 又会有什么情况呢?
还是有安全问题!!!**
上面介绍的4
中加密方法, 除了第一种方式用不了一点.
后面的三种方式都在一定程度上守护了数据安全:
- 第二种方式, 守护了 从客户端发送给服务器的数据安全
- 第三种方式, 守护了 双方的数据安全, 但是效率太慢
- 第四种方式, 则在守护了 双方的数据安全的同时, 还保证了以后正常通信的效率
但这三种方法可以做到守护了数据安全的前提是, 中间人没在协商的时候动手脚
思考一下, 如果 在 服务器给客户端发送公钥的时候, 中间人截取数据, 把 发给客户端的服务器公钥换成自己的公钥 并存储服务器的公钥. 会发生什么事呢?
如果中间人这样做了, 那么
- 客户端就会以为 中间人的公钥是服务器的公钥.
- 客户端会用中间人的公钥加密数据, 并发送给服务器
- 然后中间人可以对客户端发送的数据进行截取
- 又因为客户端实际使用 中间人的公钥加密数据, 所以中间人可以用自己的私钥解密 获取客户端发送的数据.
- 然后中间人再用 服务器的公钥 加密获取到的客户端发送的数据
- 再将加密好的数据发送给服务器.
- 服务器可以用自己私钥解密.
这就会导致, 客户端和服务器都认为 双方是在安全的通信, 但实际上, 数据已经被中间人获取了.
整个过程就像这样(假设协商用第四种方式加密):
中间人在第3
步的时候, 获取到服务器的公钥, 并替换成自己的公钥
在第5
步 客户端发送对称密钥的时候, 解密 并获取对称密钥
然后将对称密钥再用服务器公钥加密 发送给服务器.
这下, 中间人就获取了服务器的公钥 和 此次客户端与服务器加密通信的对称密钥. 而且, 客户端和服务器也不知道数据以及密钥已经泄露了
这可是一个大麻烦!! 这个麻烦第二种和第三种情况都可能出现.
如何解决这个麻烦呢?
这个麻烦出现的原因, 归根结底 是 因为客户端不知道公钥已经被掉包了, 客户端无法识别收到的包含公钥的数据是否是来自服务器的.
如果 让客户端可以识别包含公钥的数据是否直接来自服务器 就可以解决这个麻烦.
那么, 就要引入 证书
这个东西了.
证书
CA证书是一种数字证书, 它是由证书颁发机构(CA)颁发
给服务器的.
上面介绍的HTTPS
协议可能使用的加密方法都不安全, 因为 在沟通加密方式时, 客户端不能确定公钥是否正确来自服务器.
CA证书中会包含一些信息, 比如: 证书持有者相关信息、持有者公钥、域名、证书有效期等.
服务器在使用HTTPS
协议之前, 都需要先向CA申请一份数字证书. 申请到证书之后, 就可以使用HTTPS
协议了.
此时客户端和服务器建立通信时, 服务器回向客户端发送网站的证书, 然后客户端验证证书有效性、获取服务器公钥、建立加密…
CA证书的功能就是 保证客户端正确获取到服务器正确的公钥.
如何保证?
要想弄懂CA证书是如何 保证服务器公钥的正确性 的, 就要先了解CA证书的颁发流程
证书颁发流程
CA证书是 由服务器申请、由CA(证书颁发机构)颁发的.
这是一个证书大致的颁发流程:
-
服务器创建公、私钥对, 并将 公钥与其他申请信息(域名等)生成一个证书请求(
.csr
文件), 再将证书请求给CA -
CA进行审核, 并生成证书
证书的生成流程:
- CA收到证书申请
- 对申请信息进行审核
- 生成证书内容:申请者公钥、有效期、证书签名算法、颁发者等
- CA使用自己的私钥, 根据证书内容生成唯一的数字签名 (通过对证书内容的数据指纹非对称加密生成)
- 证书内容与数字签名组成CA证书
-
CA将证书颁发给服务器
服务器与客户端的证书验证流程
当服务器拥有了CA证书之后, 就可以使用HTTPS
协议了
那么, CA证书该如何使用呢? 客户端如何验证服务器公钥确实来自服务器呢?
首先, 我们要了解一个内容: 客户端(浏览器)一般是包含受信任的证书颁发机构(CA)的CA证书的, CA的CA证书里包含有CA的公钥. 操作系统中同样内置受信任CA机构的证书
你可以在浏览器的证书管理中, 查看到相应的内容
那么, 客户端验证的流程就为:
- 与服务器建立通信, 接收服务器发过来的CA证书
- 根据服务器CA证书中记录的数据指纹算法, 直接 对证书内容 使用此算法 计算数据指纹
- 根据证书颁发机构, 对比浏览器中信任的颁发机构的CA证书, 并获取颁发机构的公钥
- 使用颁发机构的公钥 对 服务器CA证书的数字签名 进行解密, 得到 证书内容的 数据指纹
- 对比 数字签名解密后得出的数据指纹 与 直接对证书内容计算得出的数据指纹
- 如果一致, 则表示服务器的CA证书没被篡改, 其中记录的服务器公钥正确. 反之则不正确
不只客户端需要对CA证书进行验证, 在服务器首次收到颁发的CA证书时, 也是需要对CA证书进行验证的, 防止CA证书已经被篡改
服务器获取CA机构的公钥, 可以从CA机构提供的地址下载
CA证书能否被篡改?
思考一个问题, CA证书能否被篡改呢?
答案是肯定的, CA证书是可以被篡改的, 甚至可以用自己的密钥 对已经被篡改的证书内容生成数字签名, 生成一个新的证书. 但是即使证书被篡改了, 也可以保证安全性.
因为:
-
如果, CA证书内容被篡改了, 那么数据指纹就会发生变化, 在验证 对比解密出的数据指纹时, 就会发生错误. 结果就是 被篡改的证书可以被发现发生了篡改
-
如果, CA证书内容被篡改了, 同时篡改人使用自己的密钥对已经被篡改的内容生成了数字签名, 这样 计算出的数据指纹 与 数字签名内的数据指纹 好像是相同的了.(其实这已经算是把证书掉包了)
但实际上是, 客户端根本无法对数字签名进行解密. 因为 篡改人的公钥客户端不知道, 即使知道了, 篡改人也不被客户端信任.
因为, 客户端对数字签名进行解密的前提是, 拥有 受信任的CA机构的公钥
篡改人的公钥, 明显是不被信任的
所以, 如果CA证书被篡改了, 客户端是可以直接发现的, 也就不会与服务器建立安全连接
5. 证书 + 非对称加密 + 对称加密**
有了证书之后, 客户端和服务器进行通信时 加密的流程, 就变成了这样:
服务器给客户端发送CA证书, 客户端验证证书, 成功就获取服务器公钥(失败就提示并且不建立连接), 然后客户端生成对称密钥, 并使用服务器公钥加密发送给服务器
最终客户端和服务器都携带有对称密钥, 实现之后的加密通信
此时, 中间人无法获取对称密钥:
此时, 也就保证了通信的安全. (当然并不绝对)
HTTPS
协议, 就是使用的 证书认证+非对称加密+对称加密 的加密方式, 进行加密通信的
本篇的HTTPS
协议就介绍到这里啦~
感谢阅读~