计算机网络-HTTPS
HTTP Secure
/HTTP over SSL
/HTTP over TLS
即工作在
SSL
(或TLS
)上的HTTP
。说白了就是加密通信的HTTP
。
SSL
: Secure Socket Layer(安全套接字层)(TLS
前身)TLS
: Transport Layer Security(传输层安全性)
定义
在 HTTP
和 TCP
之间增加了一个 安全层(安全的加密层),用于保障 HTTP
的加密传输。
即 HTTP
将数据交给 TCP
之前,先把数据交给 TLS
,由 TLS
将数据进行加密后,再往下交给 TCP
进行数据去传输。
以及对面的接受方在 TCP
层收到数据且拼接好之后,不直接交给 HTTP
层,而是先交给 TCP
层进行解密,解密完后再由 TLS
交给 HTTP
。
本质
在客户端和服务器之间用 非对称加密 协商出一套 对称密钥 ,每次发送信息之前将内容加密,收到之后解密,达到内容的加密传输。
为什么不直接用非对称加密
非对称加密由于使用了复杂了数学原理,因此计算相当复杂,如果完全使用非对称加密来加密通信内容,会严重影响用户网络通信的性能。
HTTPS (TLS) 的连接
大致流程
- 客户端请求建立
TLS
连接 - 服务器发挥证书
- 客户端验证服务器证书
- 客户端信任服务器后,和服务器协商对称密钥(此时通过非对称加密的方式协商对称密钥)
- 使用对称密码开始通信
详细流程
可以通过 WireShark 进行更加详细的查看。
客户端和服务器第一次打招呼。
客户端向服务器发送 Client Hello(大小为1字节的数据,值为1,这个数据的名字叫做 Client Hello)。
同时,也会再附加信息中发送服务器可选的
TLS
版本、可选的加密套件(对称加密算法、非对称加密算法、哈希算法)、客户端生成的随机数。服务器收到 Client Hello 后,确定双方可以共同使用的
TLS
版本、加密套件 ,以及服务端自己生成的以及随机数,并将这些信息发回给客户端,称为 Server Hello。Server Hello 也是一个单字节数据,值为2。如果没有可以共同使用的内容,那么
HTTPS
就直接建立失败。服务器发送自己的证书。
证书中主要包含了:
- 服务器的公钥(其实是个数据)
- 服务器的证书的签名(由证书签发机构的私钥对服务器证书的签名)
- 证书签发机构的公钥(用户验证这个“公钥签名”的另一个公钥)
- 证书签发机构的证书的签名
- 证书签发机构的签发机构(根证书机构)的公钥
- 服务器主机名
可以让客户端进行信息加密。客户端通过服务器的公钥进行信息加密,服务器可以通过自己的密钥进行信息的解密。
服务器公钥的签名
用私钥对服务器公钥的 Hash 值版进行一次非对称加密的计算得到的结果数据。这个数据可以被该私钥对应的公钥所解开。
如果解开签名之后的值正好等于服务器公钥经过一次 Hash 计算后的结果值,那么就证明这个源数据是没有问题的。
注意:用于解开的公钥和被签名的公钥不是同一个,它是由私钥生成的另一个公钥。
客户端验证公钥的正确性。
证书签发机构的签发机构的证书,在所有的操作系统中都默认带有一份,被认为是最可信的证书,被称为“根证书”。
当需要查询这些证书的时候,会从设备中进行查询,如果能够查询的到的话,那么第5个文件内容就是可信的了。
当证书签发机构的签发机构的公钥是可信的话,我们就可以使用这个公钥去验证第4个内容的正确性。再使用第3个内容的公钥去验证第2个内容的正确性了。
如果第2个内容是正确的话,那么说明服务器的公钥就是正确的了。
除了操作系统自带的根证书,我们也可以自行往自己的设备中安装自己需要的根证书。
注:客户端除了验证公钥是否正确,还需要验证服务器主机名是否是我们所需要到达的地址。
客户端发送
Pre-master Secret
的数据使用的服务器的公钥加密发过去的,也是一个客户端生成的随机数。
客户端和服务器都通过上述三个随机数生成一个
Master Secret
的值通过
Master Secret
就可以算出双方进行对称加密的密钥等相关的一些信息了。然后双方就可以进行加密通信了。Master Secret
会生成四个内容:- 客户端加密密钥
- 服务端加密密钥
- 客户端
MAC Secret
- 服务端
MAC Secret
为什么使用三个随机数生成数据,而不是仅使用
Pre-master Secret
来生成数据?为了防止重放攻击。通过多个随机数,防止攻击者使用一个以前收到的随机数就可以获取用户的身份认证。
重放攻击(Replay Attacks)
又称重播攻击、回放攻击,是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。重放攻击可以由发起者,也可以由拦截并重发该数据的敌方进行。
为什么客户端和服务器要使用两个加密密钥呢?
为了防止出现攻击人将客户端发送的消息重新发送给客户端,使用相同的密钥会使客户端能够解密并认为这个服务器发送的数据,从而导致数据错误。而通过两个不同的密钥,便可以防止客户端和服务器双方无法分辨数据的来源了。
注意:
- 客户端向服务端发送对称加密数据时,双方使用客户端加密密钥进行加解密操作。服务端向客户端发送对称加密数据时,双方使用服务端加密密钥进行加解密操作。
MAC Secret
。其中MAC
也即HMAC
(Hash-based Message Authentication Code 哈希运算消息认证码),可以使数据进行带密码的哈希计算。仅仅只是无密码的哈希算法容易被攻击者碰撞,但是使用带特定的密码的哈希算法就是极大的增加难度。当接收方也使用带该密码的,相同的哈希算法进行计算后,与发送过来的哈希值进行比较,如果两者一样的话,那么就可以证明数据使对方发的且是安全的。
客户端向服务器发送1个字节的数据(值为20,名称为 Change Cipher Spec),通知自己将使用加密通信。
客户端将前7步得到的数据通过客户端加密密钥以及客户端
MAC Secret
加密,然后发送给服务器。服务器对获得的结果进行验证。消息名称为 Encrypted Handshake Message。
此步之后,客户端就可以通过对称加密发送信息了。
服务器向客户端发送1个字节的数据(值为20,名称为 Change Cipher Spec),通知自己将使用加密通信。
服务器将前9步得到的数据通过服务器加密密钥以及服务器
MAC Secret
加密,然后发送给客户端。客户端对获得的结果进行验证。消息名称为 Encrypted Handshake Message。
此步之后,服务器也可以通过对称加密发送信息了。