本文正在参与 “网络协议必知必会”征文活动
先看这篇 网络协议 HTTP篇,再来看本篇应该会好一些。如果不需要,跳过即可。
想了解网络协议补充知识的话可以去这里网络协议 补充篇。
什么是HTTPS
HTTPS是在HTTP上建立SSL/TLS加密层,并对传输数据进行加密,是HTTP协议的安全版。现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。
HTTPS主要作用是:
(1)对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全;
(2)对网站服务器进行真实身份认证。
我们经常会在Web的登录页面和购物结算界面等使用HTTPS通信。使用HTTPS通信时,不再用http://
,而是改用https://
。另外,当浏览器访问HTTPS通信有效的Web网站时,浏览器的地址栏内会出现一个带锁的标记。对HTTPS的显示方式会因浏览器的不同而有所改变。
SSL 出过三个大版本,当它发展到第三个大版本的时候才被标准化,成为 TLS(传输层安全,Transport Layer Security),并被当做 TLS1.0 的版本,准确地说,TLS1.0 = SSL3.1。
为什么会有HTTPS?
我们知道http2.0以前,http传输数据都是明文传输的,http2.0/http3.0 采用二进制帧数据,因此在传输的每一个环节,数据都有可能被第三方窃取或者篡改,具体来说,HTTP 数据经过 TCP 层,然后经过WIFI路由器
、运营商
和目标服务器
,这些环节中都可能被中间人拿到数据并进行篡改,也就是我们常说的中间人攻击。
那https是服务端/客户端将数据进行加密,然后客户端/服务器进行解密,这样就可以对数据能够保护起来,虽然也被攻击过,但是也起到了一定的防护作用,并且安全性越来越高。
TLS1.2
TLS1.2其实是非常复杂的过程。
使用RSA连接的TLS1.2
对称加密
对称加密:指的是加密和解密用的是同样的密钥。如果用来加密数据,抓包直接可以抓到密钥,所以不安全。
非对称加密
非对称加密:如果有 A、 B 两把密钥,如果用 A 加密过的数据包只能用 B 解密,反之,如果用 B 加密过的数据包只能用 A 解密。
加解密计算量太大,增加服务端和客户端的负担,并且当服务器返回数据给客户端,抓包是可以抓到公钥的,同时返回的数据就会被破解出来,虽然上传数据公钥加密,黑客无法解密,所以效率不高也不安全。
对称加密和非对称加密的结合
综上所述,单独使用对称加密,非对称加密都是不安全的,那么将它们结合在一起确实一个不错的解决方案。
当 TCP 建立连接之后。
第一步
首先浏览器向服务器发送对称加密套件列表、非对称加密套件列表和随机数 client-random;
第二步
服务器保存随机数 client-random,选择对称加密和非对称加密的套件,然后生成随机数 service-random,向浏览器发送选择的加密套件、service-random 和公钥;
第三步
浏览器保存公钥,并生成随机数 pre-master,然后利用公钥对 pre-master 加密,并向服务器发送加密后的数据;最后服务器拿出自己的私钥,解密出 pre-master 数据,并返回确认消息。
第四步
现在浏览器和服务器有三样相同的凭证:client_random、server_random和pre-master。然后两者用相同的对称加密方法和这三个随机数,生成最终的密钥
。
第五步
然后浏览器和服务器尽管用一样的密钥进行通信,即使用对称加密
。
小结
pre-master是很安全的,因为需要私钥解密才能把pre-master算出来,据统计可以通过穷举解密,但是这种方式解密是不是难度太大了。
但是这种方式一旦被破解了,历史信息都是可以被查看到的,因为私钥是不变的,那么要解决这个问题,使用了ECDHE算法。
使用ECDHE的TLS1.2
当 TCP 建立连接之后。
第一步
客户端发送客户端的TLS版本号,加密密码套件列表,还有客户端随机生成的Client Random,我们可以在开发者工具上面的Security中查看TLS版本,密码套件。
第二步
服务端收到客户端信息后,确认TLS版本号,选择出此次连接的加密方法,也是ECDHE,把Client Random保存起来,方便以后使用,接着服务端也生成了一个Server Random,和 Serve Prams「也就是ECDHE公钥」,还有私钥前面认证,CA证书,用来证明服务端身份。
第三步
客户端收到这么多信息后,把Server Random, Serve Prams,保存起来,方便以后使用,接着使用CA证书,验证服务器身份,并且通过刚刚确认的加密方法生成Client Params,接着使用CA证书的公钥进行加密,把Client Params传递到服务端,这时候服务端和客户端拥有了 Client Random、Server Random、Client Params、Serve Prams。
第四步
服务端和客户端同步进行,利用ECDHE算法,以Client Params、Server Params为参数,还有服务端使用自己的私钥,客户端使用自己的私钥,各自生成Pre-Master,这里的Pre-Master是安全的关键,利用ECDHE算法保证黑客无法算法真正的Pre-Master。这里其实是利用了椭圆曲线离散对数,比较复杂。
第五步
生成完Pre-Master后,它只是一个随机数,为安全再做一层保障。接着客户端和服务端利用三个随机数:Client Random、Server Random 和 Pre-Master。用这三个作为原始材料,使用PRF算法,然后再经过想这样SHA384的摘要算法再进行签名, 就可以生成用于加密会话的主密钥,叫“Master Secret”。而黑客因为拿不到“Pre-Master”,所以也就得不到主密钥。三个随机数,又增加的随机性,每次建立https连接都不一样,所以黑客破解的成本太高了。
第六步
主密钥还会衍生出会话密钥,等等,都是基于这个主密钥的。
就和上面一样,使用AES对称加密算法加密会话密钥进行传输数据,因为会话密钥是用来传递HTTPS的数据使用的。
加密方法都有什么?
比如:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ECDHE:使用进行密钥交换
RSA:非对称加密
AES_128_GCM:使用128位GCM分组工作模式的AES进行消息和会话密钥的对称加密
SHA256:摘要算法, 使用摘要算法,再用私钥对摘要签名的原因是因为非对称加密算法效率不高,摘要数据量小又能代表完整数据,对摘要签名即可以达到对完整数据签名的效果。
小结
ECDHE 即 “短暂-椭圆曲线-迪菲-赫尔曼(ephemeral Elliptic Curve Diffie -Hellman)
1.使用ECDHE算法的话可以提高安全性,因为可以做到前向加密,每一个https连接都是随机的密钥。
2.效率高,因为使用了 ECDHE,客户端可以不用等到服务器发回“Finished”确认握手完毕,立即就发出 HTTP 报文,省去了一个消息往返的时间浪费。这个叫“TLS False Start”,意思就是“抢跑”,不等连接完全建立就提前发应用数据,提高传输的效率。
TLS1.3
由于TLS1.2是2008年的协议,所以在2018年TLS1.3出世,TLS1.2其实安全性,性能方面都是存在多多少少的问题,如RSA握手不安全、连接时需要2个RTT。
TLS1.3也是受了很多的限制,想HTTP3.0一样,需要考虑的历史遗留的问题。
所以TLS1.3是向后兼容TLS1.2的。
TLS1.3相比TLS1.2有什么不同?
兼容性
因为设备硬化的问题,导致新的算法不一定能够使用,就会导致HTTPS握手失败,TLS1.3为了更好的兼容性,所以增加了可以自动降级TLS1.2的辨别方式,扩展协议(Extension Protocol),如果TLS无法判断该字段,则认为是TLS1.2。
Handshake Protocol: Client Hello
Version: TLS 1.2 (0x0303)
Extension: supported_versions (len=11)
Supported Version: TLS 1.3 (0x0304)
Supported Version: TLS 1.2 (0x0303)
安全性
对TLS1.2已知的攻击有 BEAST、BREACH、CRIME、FREAK、LUCKY13、POODLE、ROBOT。
所以TLS1.3对一些不安全的算法进行剔除和替换。
- 伪随机数函数由 PRF 升级为 HKDF(HMAC-based Extract-and-Expand Key Derivation Function);
- 明确禁止在记录协议里使用压缩;废除了 RC4、DES 对称加密算法;
- 废除了 ECB、CBC 等传统分组模式;废除了 MD5、SHA1、SHA-224 摘要算法;
- 废除了 RSA、DH 密钥交换算法和许多命名曲线。
最终只保留了这五种加密套件算法
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
- TLS_CHACHA20_POLY1305_SHA256
性能
在TLS1.2连接是需要2个RTT的,所以是一个特别费时的操作,现在TLS做到了只需要1个RTT,甚至只需要0个RTT,是有条件的,需要使用pre_shared_key和early_data。
TLS1.3连接详细过程
建立完TCP连接后。
第一步
客户端发送TLS版本号,密码套件列表,Client Random ,因为服务端需要提前使用ECDHE算法,那么客户端这边将参数尽量都给它,supported_versions 可以确认服务端是否能支持TLS1.3版本,supported_groups 是支持的曲线列表,key_share 是曲线对应的参数,服务端就可以拿到TLS1.2中的Client Params就是key_share中的参数。
第二步
服务端确认兼容TLS1.3版本后,确认使用的那个密码套件,并把Server Params传递回去,存放在key_share上,并进行私钥签名。
这时候服务器其实所有的参数都全了,利用Client Params和 Server Params 和ECDHE算法算出Pre-Master,然后再使用HKDF算法Master Secret。
然后使用Master Secret衍生会话密钥,接着通过会话密钥加密服务端证书,然后再传递过去客户端。
第三步
客户端验证证书,然后和第二步生成Master Secret的路径一样,接着客户端和服务端就可以通讯。
这里其实我还有疑问的是,客户端验证证书是被会话密钥解密过的,怎么解密我还需要去研究。
小结
HTTPS并不是一个新的协议, 它在HTTP
和TCP
的传输中建立了一个安全层,利用对称加密
和非对称机密
结合数字证书认证的方式,让传输过程的安全性大大提高。
数字证书(CA数字证书)
尽管通过两者加密方式的结合,能够很好地实现加密传输,但实际上还是存在一些问题。黑客如果采用 DNS 劫持,将目标地址替换成黑客服务器的地址,然后黑客自己造一份公钥和私钥,照样能进行数据传输。而对于浏览器用户而言,他是不知道自己正在访问一个危险的服务器的。
HTTPS的数字证书认证的步骤,目的就是让服务器证明自己的身份。
银行转账有时候也需要验证客户端身份的,那么是通过U盾来给操作系统安装证书,来证明它当前环境是安全的。
如何申请证书呢?
第一步:网站开发者填写网站公钥、站点资料、公司资料等信息,提交给 CA 机构。
第二步:CA 机构会审核相关内容的真实性;审核通过后,CA 机构会拿出自己的私钥,对表单的内容进行一连串操作,包括了对明文资料进行 Hash 计算得出信息摘要, 利用 CA 的私钥加密信息摘要得出数字签名,最后将数字签名也写在表单上,并将其返还给极客时间,这样就完成了一次数字证书的申请操作。
这样一个CA数字证书,里面含有公钥,网站基础信息,CA的数字签名。
浏览器验证证书的流程?
现在有了证书后就可以应用到https中了,那么服务端发送给浏览器,浏览器怎么验证服务端身份呢?
浏览器需要验证证书的有效期、证书是否被 CA 吊销、证书是否是合法的 CA 机构颁发的。
有效期验证
可以在基础信息上面验证就可以了
证书是否被CA吊销
可以通过两种方式验证是否被吊销,一种是下载吊销证书列表 -CRL (Certificate Revocation Lists),第二种是在线验证方式 -OCSP (Online Certificate Status Protocol) 。
证书是否是合法的 CA 机构颁发的
第一步:在数字证书上有网站的公钥和基础信息,经过Hash算法,得到信息摘要。
第二步:将CA的数字证书中的公钥提供给网站数字证书中的CA数字签名,因为上面已经说了CA证书签名就是CA机构拿出私钥加密,就是签名完成,那么现在使用公钥解密即可得到信息摘要。
第三步:判断第一步和第二步中的信息摘要是否相等,相等则认为是和发机构颁发的。
这里引发一个问题是CA的数字证书是否可信?
我们知道第二个信息摘要是通过CA公钥解密的,它使用的CA的数字证书是否合法呢?
数字证书链
根 CA(Root CAs)
需要通过 WebTrust 国际安全审计认证,目前只有两个协会可以颁发,AICPA(美国注册会计师协会) 和 CICA(加拿大注册会计师协会) 共同制定的安全审计标准,主要对互联网服务商的系统及业务运作逻辑安全性、保密性等共计七项内容进行近乎严苛的审查和鉴证。 只有通过 WebTrust 国际安全审计认证,根证书才能预装到主流的操作系统,并成为一个可信的认证机构。
中间 CA(Intermediates CAs)
中间 CA通过根CA证书认证才可以成为可信的中间CA,然后中间CA又可以认证中间CA,这样下去就形成了一颗树,叫做证书证书链。
那回到刚刚那个问题,怎么验证CA的数字证书是否合法,解决这个问题,只有在本地的操作系统来认证,只要找到了颁发的根CA证书就认为这个CA的数字证书是合法的。
各位看官如遇上不理解的地方,或者我文章有不足、错误的地方,欢迎在评论区指出,感谢阅读。