从零设计一个HTTPS协议

背景

HTTP协议的网络传输是明文的,因此HTTP通信存在如下三个问题:

  • 被监听:在客户端与服务端的通信过程中,数据在链路的任何一点都有可能被劫持。比如请求中携带了账号和密码,一旦请求所经过的某个路由器被劫持,那么明文的账号和密码将会被暴露。

  • 被篡改:第三方对通信过程中的数据进行篡改。比如你向某银行服务端发起转账请求,第三方在请求所经过的某个路由器上将转账的账户和金额进行篡改,你的钱就被转入其他地方了。

  • 被伪装:对于客户端来说,你无法保证服务端是你认为的那个服务端。比如你在和某银行服务端通信,有可能你发出的所有请求都在某个路由器上被第三方劫持,第三方不再将这些请求向外转发,并且自己给你发送了响应。


    HTTP通信.png

鉴于HTTP协议的问题,我们需要基于HTTP设计一种安全的网络协议,来解决以上的问题。

对称加密

要解决以上问题,最先想到的就是对称加密。在HTTP层之下加一个加密层,用对称加密对发送的数据进行加密,对接收的数据进行解密。

加密之后,即使获取的数据被劫持,第三方也无法解密,这样就可以避免监听和篡改问题了。此外,由于第三方没有对称密钥,也无法伪装成服务端与客户端进行加密通信。


HTTP+加密通信.png

但是,客户端和服务端之间要如何沟通对称密钥呢?网络是不安全的,只能通过线下的方式来沟通密钥,但互联网中海量的客户端和服务端如何进行线下沟通呢?这显然不现实。

非对称加密

为了解决密钥沟通问题,我们可以使用非对称加密,非对称加密拥有一对密钥,分别为公钥和私钥,公钥加密的数据可以用私钥解密,私钥加密的数据可以用公钥解密。

于是客户端可以在网上向服务端暴露自己的公钥,服务端可以在网上向客户端暴露自己的公钥。当客户端向服务端发送数据时,用服务端公钥加密,服务端收到后用自己的私钥解密;服务端向客户端响应数据时,用客户端的公钥加密,客户端收到后用自己的私钥解密。

但是非对称加密有一个比较严重的问题,就是加密解密的速度比较慢,这会大大的影响客户端与服务端的沟通速度。

非对称加密+对称加密

我们可以结合两种加密方式,先用非对称加密进行对称密钥的沟通,再用沟通好的对称密钥对后续的通信进行加密。

到此,看似所有问题都已解决,但其实仍然有一个严重的隐患。在前文的对称加密通信中,我们提到过线下交换密钥,通过线下交换,我们不仅可以防止密钥暴露,还可以确认对方身份。但是在网上我们如何确认我们所获得得服务端公钥确实是该服务端的公钥,有没有可能第三方劫持了客户端的网络,将自己的公钥伪装成服务端的公钥发送给客户端,客户端的所有信息都用第三方的公钥加了密并发送了出去。这样的话,监听、篡改、伪装问题仍然无法得到解决。


公钥确认问题.png

所以,我们还有最后一个问题需要解决,即:我们如何确保客户端收到的服务端公钥确实是服务端的公钥?

CA(Certificate Authority)

既然在通信过程中,双方无法通过自身判断出对方确实是我期望的对方,那么我们就需要引入一个有公信力的第三方组织来帮助我们判断对方的真实身份。

CA通过线上或者线下的方式确认服务端的身份,并给服务端颁发证书,证书中包含服务端的公钥信息。此外,操作系统还内嵌了判断合法证书的方法。

于是,当客户端收到证书时,先判断证书是否合法,若合法就可以确认服务端的身份,并提取出证书中服务端的公钥。至此,客户端就可以确保收到的服务端公钥确实是服务端公钥,而不是第三方公钥了。

确认服务端公钥之后,再结合非对称加密生成对称密钥,再用对称密钥进行通信,就可以确保通信安全了。

总结

HTTPS全称为HTTP over SecureSocket Layer,即HTTPS为工作在安全层之上的HTTP。文中的加密层即所谓的安全层,而在实际的HTTPS协议中,安全层的协议有TLS和SSL。根据协议栈的分层原理,HTTP层对加密并无感知,安全层负责所有加密相关的功能。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容