从头到尾谈一下HTTPS
引言
“你能谈一下HTTPS吗?”
“一种比HTTP安全的协议。”
“...”
如果面试这样说的话那差不多就gg了,其实HTTPS要展开回答的话内容还挺丰富的。本篇文章详细介绍了HTTPS是什么、为什么安全以及实现安全的方法,一起来学习吧。
本文略长,请保持耐心。
https是什么?
HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版。之所以安全是因为它在将HTTP报文发送给TCP之前,先将其发送给了一个安全层(通过SSL协议实现)对报文进行加密。
报文加密的优点
- 保证客户端和服务器的对话不会被其他人窃听
- 保证双方发送的数据不会中途被修改
- 确保双方的身份是真实客户端/服务器而不是伪造的客户端/服务器
不妨将报文想象成A给B写的一封信,A将信放在一个有锁的盒子里,那么旁人就不能获取信的内容也不能篡改信了。
加密机制
先了解几个术语
- 明文:未加密的报文
- 密文:通过加密算法加密后的报文
- 密钥:改变加密算法行为的参数
比如我们有一个加密函数,算法如下
function E(key, p) { // 将p的每一个字母向右移动key位,比如key为3则A-->D、B-->E... } E(3, "AB"); // DE
明文: "AB" ------ 密文: "DE" ------ 密钥:3
如果我们的密钥不一样那么我们的加密函数执行结果就会不同。
下面来看一下常见的几种加密机制。
对称加密
我们之前说过,让报文加密是为了保证我两的聊天内容是秘密的,只有我两能看懂,别人看不懂。那么我们要约定一个加密方式,比如咱俩递小纸条交流的时候把小纸条装在一个盒子里,然后只有我们有这个盒子的钥匙。其他人就算拿到这个盒子他也打不开,那就无从窃取内容了。
对称加密就是这个意思:发送方用密钥将明文加密,接收方用同样的密钥解密。
虽然安全性得到了保障,但是还是存在两个问题:
- 发送双方约定密钥时需要将密钥在网络传输,可能会造成密钥泄露,安全得不到保障。
- 就是发送方与接收方在互相对话之前一定要有有一个共享密钥。试想,如果N个客户端都要与服务器建立安全通信,那么服务器需要保存N个密钥,N和客户端和N个服务器通信,那么将有N^2个密钥,管理起来非常不便。
非对称加密
非对称加密和对称加密是反着干的,对称加密是使用同一个密钥,而非对称加密使用了两个不同的密钥:公钥、私钥,一个密钥加密的内容只能由另一个密钥解开。
公钥是众所周知的,而私钥只有主机才持有。
服务器生成了公钥A和私钥B,当客户端想给该服务器发送报文时,首先找到服务器的公钥,然后根据公钥A将报文加密,服务器用私钥B解密。同理,当服务器想给该客户端发送报文时,首先找到客户端的公钥C,然后根据公钥C将报文加密,客户端用自己的私钥D解密。
在确保了信息安全的同时又可以方便密钥的管理。
由此,对称加密和非对称加密的区别是:
. | 对称加密 | 非对称加密 |
---|---|---|
密钥 | 加密解密用相同密钥 | 公钥、私钥,一个加密另一个解密 |
密钥管理 | 密钥数量大,不方便 | 每个主机只需管理一对公钥、私钥 |
安全性 | 不安全(并非该机制不安全,而是双方在约定密钥时可能会密钥泄露) | 安全(不需要通过对话约定密钥) |
加/解密速度 | 快 | 慢 |
那HTTPS是采用的什么机制呢?
HTTPS加密机制
剧透,HTTPS对报文采用的对称加密。
完整的一次HTTPS交流
(1) 客户端通过TCP三次握手建立到服务器端口443(HTTPS的默认端口)的TCP连接
(2) 客户端通过SSL握手建立安全层
(3) 客户端发送http报文到SSL安全层,安全层将报文加密后发给TCP --> IP --> ...
(4) 同理服务器发送响应,客户端接收后通过SSL安全层解密发给应用层
(5) SSL安全层关闭通知
(6) TCP关闭连接
从上面的描述可以清晰的看到我们的报文加密/解密都是在SSL安全层执行。
那么安全层是怎么加密的?密钥又是怎么约定的?这一切的一切都得仔细聊聊第(2)步骤。
SSL握手
(1) 客户端向服务器发送可供选择的加密算法并请求证书。
客户端说:“嘿,小子。我这里有一堆我支持的加密算法,你选一个你喜欢的发给我。对了,顺便把你的身份证复印件发给我看看,我怕我连接的服务器是伪造的。”
(2) 服务器发送选中的加密算法和证书
服务器说:“emmm...我看加密算法A挺好的,咱俩就用这个吧。证书也发给你,证明我不是坏人。”
(3) 客户端保存服务器选择的加密算法和秘钥A以作为日后加密,将A用服务器的公钥B加密后发给服务器,服务器用自己的秘钥C解密后得到A,从此客户端和服务器都用约定的加密算法以及秘钥A进行对称加密。
(看到了伐?先用非对称加密在网络中传输对称加密的秘钥A,之后对报文都是采用对称加密啦。)
(4) 客户端和服务器互相告知,开始加密过程。
在SSL握手之后我们就可以开开心心的发送和接收加密报文啦。
以上是HTTPS加密的全过程,不过还不足以构成完整的HTTPS,因为完整的HTTPS要保障两个方面的安全:报文安全、身份安全,加密只能保证报文是安全的,不能保证身份是正确的。
试想,A和B互相写信并且交换盒子钥匙,然后将信放盒子里寄出去,上面的加密行为可以让A和B之间写的信内容不会被他人获取,但是如果一开始和A通信的就不是B呢?是窃取者C伪装成B和A通信,那么A会和C在SSL的时候就交流钥匙然后C可以窃取A写给B的信的内容。
身份的认证我们用数字证书。
数字证书
含有数字证书的报文的结构:
刚刚SSL握手的第(1)步还记得伐?客户端向服务器索要证书,这个证书是服务器可以证明自己身份的东西,该证书里包含了服务器的一些基本信息,比如站点的DNS主机名、该站点组织名、站点的公钥(发公钥就是为了让客户端SSL方便执行握手(3))等,以及证书的序列号、证书签名算法、过期日期等证书信息。
数字签名
证书是一个站点的身份证,但是身份证也可以被伪造,为了保证这个证书是真的我们需要数字签名。我们会将证书内容用签名算法生成一个值,我们称之为“摘要”。然后将该摘要用主机的私钥加密,加密后的内容就是我们的数字签名。
当客户端收到附带数字签名的数字证书时,会通过数字证书中的证书签名算法将该证书生成一个摘要,在用服务器众所周知的公钥解密数字签名,看得到的摘要是否相同,相同那就说明证书是真的。
如果公钥解密后得到的摘要与生成的摘要不符那么可能有两种情况
- 发送方身份不是目的主机
- 目的主机发送的证书被篡改
数字证书和加密就构成了一个完整的HTTPS事务。
总结
- HTTPS之所以安全是因为有两个保障
- 双方的会话内容加密,旁人不能窃取
- 双方的身份是真实的,防止窃取者伪造身份
- 内容安全
- 非对称加密机制加密“对称加密所需密钥”
- 对称加密机制加密报文
- 身份安全
- 数字证书
- 数字签名
- 确认发送方身份
- 确认证书未被篡改
参考书籍:
《HTTP权威指南》