之前看了一些网上关于https的文章,感觉都讲的不够完善,整篇看下来还是觉得有几个疑问点,最近学习了极客时间《透视HTTP协议》,稍微能摸清楚https的工作,写一写加强印象。
什么是安全
通常认为,通信过程具备了以下4个特性,可以认为安全:机密性,完整性,身份认证,不可否认。
- 机密性
指数据保密的,只有通信的对方能知道数据的内容,数据对其他方是不可见的 - 完整性
机密性虽然保证了数据不可被窃取,但是不能防止被篡改,如果通信过程数据直接被调包或者被修改,那么也是不安全的 - 身份验证
指能确认对方的身份,保证“我”在和“你”在通信而不是“他”,没有身份验证,通信的是“他”,那么再怎么机密的数据也是白搭 - 不可否认
“我”通过只有“你”知道的事情回应“你”,那么“你”就是正确的“你”
什么是HTTPS
HTTPS是运行在SSL/TLS上的HTTP,只要弄懂了SSL/TSL就弄懂了HTTPS,而SSL/TLS是在OSI模型中处于第5层会话层中,目前运用最广泛的TLS是v1.2版本,最新的v1.3兼容了v1.2,且强大了很多。
TLS由记录协议,握手协议,警告协议,变更密码协议,扩展协议等几个子协议组成,综合使用了对称加密,非对称加密,身份验证等多个前沿密码学技术。
加密
对称加密
安全的第1个特性是机密性,那么实现机密性最常用的手段就是对数据进行“加密”,把数据通过某种形式转化为谁都看不懂的乱码,只有特定的“钥匙”的人才能解密数据。加密可以分为两大类:对称加密和非对称加密。
对称加密的加密和解密的密钥都是同一个,所以是“对称”的,只要保证了密钥只有通信双方持有,那么整个通信过程就具有了机密性。
目前最常用的对称加密算法是AES(advanced encryption standard),安全强度高,性能也很好,所以最流行。
分组模式
对称加密还有个分组模式的概念,他可以让加密算法用固定长度的密钥加密任意长度的明文,即小秘密转化为大秘密,将明文按照一定的规则切分,然后分别对明文片段进行加密,再整合成一起。现在最常见的分组模式是GCM/CCM/Poly1305,
非对称加密
对称加密最大的问题就是如何让通信两方都知道一个密钥,总不能为了传输这个密钥再用另一个密钥进行加密吧,那就是“鸡生蛋,蛋生鸡”的问题没完没了了。
所以非对称加密就出来了。它有两个密钥,一个是“公钥”,一个是“私钥”,两个密钥不同,所以“不对称”,私钥必须严格保密,公钥可以公开给任何人使用。
这里有个特别的“单向性”,公钥加密的数据只可以用私钥解密,反之私钥加密的数据只可以用公钥解密,常见算法有RSA/ECC。
RSA
在TLS1.2版本里最常用的非对称加密算法,由于不具有“向前安全”,所以在1.3版本中被弃用了。
ECC
是非对称加密算法的后起之秀,他基于“椭圆曲线离散对数”的数学难题,用特定的曲线方程和基点生成一个公钥和一个私钥。子算法ECDHE用于密钥交换,ECDSA用于数字签名。
混合加密
为什么TLS不直接使用非对称加密呢
- 因为非对称加密和解密的过程比对称加密慢太多,导致在通信的过程当中需要非常长的时间,通信龟速,实用性为0,RSA2048的加解密大约是15KB/s,而AES128则是13MB/s,相差了差不多一千倍。
- 由于公钥是公开的,那么客户端的数据被窃取修改,第三方一样可以用公钥加密篡改后的数据,所以要用非对称加密进行通信,客户端需要验证服务端的身份的同时,服务端也需要验证客户端的身份,这是不现实的,要海量的客户端的身份谈何容易。
所以TLS只是用非对称加密算法让双方获得一个对称加密算法的密钥,后续的通信使用该密钥进行。
数字签名和证书
虽然有了机密性,但是离安全还差很远
黑客虽然拿不到密钥,但是可以通过窃听收集足够多的密文,尝试修改/重组后发给服务器,因为没有完整性检查,服务器正常返回,黑客可以通过服务器的响应获取进一步线索,最终破解密钥。
另外,黑客也可以伪造公钥发布,如果客户端拿到了假的公钥匙,那么再怎么加密都没有用了,被黑客直接拦截,直接裸奔。。
摘要
实现完整性的手段主要是摘要算法,摘要意思就是原文的总结,概括,一个原文通过一种摘要算法只有一个摘要,所以摘要可以认为是原文的“指纹”,MD5和SHA-1是之前常见的摘要算法,但是由于安全性不足,被弃用了,现在常用的是SHA-2。
数字签名
现实生活中解决身份认证的常见的有盖章,签名。同样的,在通信中要想实现身份认证,首先得有个唯一的东西只要你拥有——那就是非对称加密中的私钥。使用私钥加密摘要,就能够实现数字签名,实现了身份认证的同时也实现了不可否认。
数字证书和CA
综合上述,我们已经实现了安全的4大特性,是不是ok了?
不是。
这样还有公钥的信任,因为谁都可以发布公钥,我们怎么证明这个公钥就是通信对方的公钥呢?
只能引入“可信的第三方”,这个第三方就是我们常说的CA,由他来给各个公钥签名,用自身的信誉做担保,构建起公钥的信任链。
CA对公钥的签名认证也是由一定格式的,包括序列号,用途,颁发者,有效时间,公钥等等,再打一个包再签名,形成一个数字证书。
HTTPS建立连接
图上的每一个直线代表的是一个记录协议,多个记录协议会在一个tcp包中一同送出。
ECDHE握手过程
- 在tcp建立连接后,浏览器会先发一个client hello,包含由TLS支持的版本号,支持的密码套件,还有一个随机数client random,用于后续生成会话密钥。
- 服务端收到后,会返回一个server hello,包含确定TLS版本号,选取其中一组密码套件,比如TLS_ECHDHE_RSA_WITH_AES256_GCM_SHA384,意思是非对称加密算法选取ECHDHE+RSA,对称加密算法AES256,分组模式GCM,摘要加密算法SHA384,还有一个随机数server random,这个同样用于后续生成会话密钥。
然后,服务器发送证书,由于服务器选择的是椭圆曲线ECHDHE的加密算法,所以又发送来一个server key exchanges,里面是椭圆曲线的公钥server params,再加上自己的私钥签名,防止server params被篡改。 - 客户端拿到了服务端的响应,这时开始验证服务端发送过来的证书是否可信,开始走证书链逐级验证:
证书是被CA签名了的,所以此时根据该证书的颁发者,拿到颁发者的公钥,解密出摘要,再根据摘要算法对证书内容进行摘要计算,如果计算结果跟证书上的摘要一致,则验证了完整性和不可否认。如果该颁发者不是1级CA,那么需要验证该颁发者的身份,根据上述同样的操作验证颁发者的证书,直到根级证书。如果在此过程都验证正确,那么该颁发者可信,从而该服务器的证书可信,达到身份验证。
验证完成后,客户端根据服务器证书上的公钥,解密出server key exchange的摘要,确认无误后,得到了server params。然后客户端按照密码套件,也生成了一个椭圆曲线的公钥(client params)和私钥,用client key exchange发送client params给服务端。 - 现在两方都有椭圆曲线自己的私钥和对方的公钥,生成一个叫做pre-master的随机数,神奇的算法让双发生成的随机数是一致的,由于私钥并没有在通信中公开,所以pre-master也没有在通信中公开,所以这个随机数在本次通信中只要双发知道。
- 双方根据client random , server random, pre-master三个随机数计算得到master secret,这个就是用于后面通信的对称密钥。
-
客户端发送一个change cipher spec和finished。再将之前发送的所有数据做个摘要,再用密钥加密一下,让服务器验证一下。
- 这里客户端可以马上进行https的通信,就是抢跑,无需等待服务器的回应,因为双方都已经在之前的握手中确定可以知道主密钥了。减少0.5个rtt。
- 服务器验证完成后,发送一个change cipher spec和finished,之后的通信就开始密文交流。
RSA握手过程
大体流程跟上述一致,只是pre-master不再通过算法生成,而是客户端直接生成随机数,然后用服务器的公钥加密,通过发送一个client key exchange发送给服务器,那此时双方也实现了共享3个随机参数。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。