HTTPS加密传输
开篇诗两句:
会当凌绝顶,一览众山小。 ——杜甫《望岳》
HTTPS 概述
安全性
通常在通信过程中,具备如下四个特性就可以认为是”安全”的:(1)机密性(2)完整性(3)身份认证(4)不可否认
HTTPS协议
HTTPS默认端口号443,其他的特性与HTTP完全相同(除了”明文”和”不安全”)
原本HTTP的下层传输协议是TCP/IP协议,但是HTTPS协议的下层传输协议是SSL/TLS协议,SSL/TLS协议是会话层协议,底层实际使用还是TCP/IP协议。HTTP + SSL/TLS = HTTPS
SSL(安全套接层,Secure Sockets Layer)在1999年被互联网工程组IETF改名为TLS(传输层安全,Transport Layer Security)
TLS由记录协议、握手协议、告警协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术
密钥交换算法+签名算法+对称加密算法+摘要算法,例如:ECDHE-RSA-AES256-GCM-SHA384
对称加密和非对称加密(机密性)
对称加密
对称加密:加密和解密过程都使用同一个密钥
TLS提供了很多对称加密算法,比如RC4、DES、3DES、AES、ChaCha20等,但前三种算法都被认为是不安全的,通常都禁止使用,目前常用的只有AES和ChaCha20
加密分组模式:用固定长度的密钥加密任意长度的明文。
最早有ECB、CBC、CFB、OFB等几种分组模式,但都陆续被发现有安全漏洞,所以现在基本都不怎么用了。常用的是GCM、CCM和Poly1305。
两者组合起来就是TLS中定义的对称加密算法,例如AES128-GCM
对称加密的问题在于密钥交换过程的安全性
非对称加密
非对称加密有一个”公钥“和一个”私钥“,公钥可以给任何人使用,私钥则必须严格保密。公钥加密之后只能由私钥解密,反之亦是。
网络传输过程中发送方通过公钥加密,接收方通过私钥解密,即可以解决对称加密过程中密钥交换的问题。
当时非对称加密也有非常打的缺点:效率很低
TLS里只有很少的几种非对称加密算法,比如DH、DSA、RSA、ECC等。
混合加密
为了解决对称加密的密钥交换时安全性的问题和非对称加密效率低的问题,采用混合加密的方式。
使用非对称加密算法加密用于会话的密钥,交换密钥之后采用对称加密的方式进行通信。这样只需要最开始对会话密钥进行加密,数据量很小且只需要加密一次。
摘要算法(完整性)
通过摘要算法将任意长度的数据压缩成固定长度,而且时独一无二的字符串。摘要算法具有单向性,只能加密不能解密。摘要算法实际上是可能存在冲突的,好的摘要算法应该仅可减少发生冲突的可能性。
摘要算法有MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),但是这两个算法的安全性比较低,已经在TLS中禁止使用了。目前TLS推荐的摘要算法时SHA-2。
在传输过程中,将原文+摘要同时使用会话密钥进行加密传输,接收方接收到消息之后,通过会话密钥解密,再通过摘要算法对原文进行计算,对比计算结果和消息中的摘要,以此来判断原文的完整性。
数字签名(身份认证,不可否认)
通过加密算法和摘要算法已经能够保证通信过程的机密性和完整性了,但是还是存在一个问题,就是如何保证公钥和私钥是正确的,如果有人伪造网站,发布假的公钥,这个时候客户端使用假的公钥进行通信就会导致信息泄露。
正常情况进行通信时,是公钥加密,私钥解密。但是数字签名是通过私钥加密,公钥解密的方式来证明通信方的身份。由于私钥是不对外公开的,所以其他人是不能伪造私钥的。
由于数字签名采用的也是非对称加密,所以加密效率是最大的问题,为了提高效率,数字签名不会对原文进行加密,而是对原味的摘要(定长字符串)进行加密,减少加密数据量提高效率。
接收方接收到数字签名之后,通过公钥解密,就能判断通信方的身份。
数字证书和CA
如果任何人都可以发布公钥,就没有办法判断公钥是否是想要通信的服务端发布的公钥。
所以服务端需要通过一种方式来证明发布的公钥是自己发布的,一种方式就是用另外一个私钥对发布的公钥进行数字签名。但是这种方式会陷入无限递归,如何验证新的公钥的安全性。
解决这个问题的方式就是由第三方机构对公钥进行数字签名,CA(Certificate Authority,证书认证机构),CA需要用自身的信誉保证公钥不能被伪造。CA不是直接将公钥绑定再持有者身上就完事了,需要将序列号,用途,颁发者,有效时间等信息打成包再签名,形成”数字证书“。本质上数字证书可以理解成由CA对公钥的数字签名。
证书体系最终关键还是依靠”信任“,并且如果CA出现问题,例如CA被攻陷,CA存在恶意,就会导致整个信任链出现问题。
TLS连接建立
TLS底层使用的仍然是TCP/IP协议,所以在建立TLS连接之前需要建立TCP连接。
此外,由于底层使用的是TCP连接,TCP本身是有ACK机制,所以TLS本身不需要自己实现ACK。