1.什么是https
HTTP的特性是明文传输(指不加密),因此在传输的每一个环节,数据都有可能被第三方窃取或者篡改,具体来说,HTTP 数据经过 TCP 层,然后经过WIFI路由器、运营商和目标服务器,这些环节中都可能被中间人拿到数据并进行篡改,也就是我们常说的中间人攻击。
HTTPS并不是一个新的协议.只是http通信接口部分用SSL和TLS协议代替而已。通常,http直接和tcp通信。当使用ssL时,演变成先和SSL通信再有SSL和和tcp通信了。简言之,https就是身披SSL这层外壳的http
http + 加密 +认证 + 完整性保护 = https
HTTPS并不是一个新的协议, 它在HTTP和TCP的传输中建立了一个安全层,利用对称加密和非对称机密结合数字证书认证的方式,让传输过程的安全性大大提高。
2.什么是对称加密和非对称加密
- 对称密钥加密:加密和解密同用一个密钥的方式称为共享密钥加密/对称密钥加密
- 非对称密钥加密:加密解密使用不同的密钥,即两把密钥:公钥可公布用来加密,私钥不可公布自己己有,用来将 已经用公钥加密的密文解密出来。
困境:对称加密和非对称加密,只用前者会有安全隐患,只用后者性能消耗又太大。
因此将两者结合,保证性能的同时又能保证安全呢。
在交换密钥环节使用公开密钥方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。
3.什么是数字证书认证机构(CA)
引入背景:
尽管通过两者加密方式的结合,能够很好地实现加密传输,但实际上还是存在一些问题。黑客如果采用 DNS 劫持,将目标地址替换成黑客服务器的地址,然后黑客自己造一份公钥和私钥,照样能进行数据传输。而对于浏览器用户而言,他是不知道自己正在访问一个危险的服务器的。
事实上HTTPS在上述结合对称和非对称加密的基础上,又添加了数字证书认证的步骤。其目的就是让服务器证明自己的身份。
为了获取这个证书,服务器运营者需要向第三方认证机构获取授权,这个第三方机构也叫CA(Certificate Authority), 认证通过后 CA 会会对已申请的公开密钥做数字签名,然后分配给这个已签名的公开密钥,并将该公开密钥放入数字证书后绑定在一起给服务器。服务器会将这份CA颁发的数字证书发给客户端,以进行公开密钥加密方式通信。
这个数字证书有两个作用:
- 服务器向浏览器证明自己的身份。
- 把公钥传给浏览器。
当服务器传送server_random、加密方法的时候,顺便会带上数字证书(包含了公钥), 接着浏览器接收之后就会开始验证数字证书。如果验证通过,那么后面的过程照常进行,否则拒绝执行。
认证过程:
浏览器拿到数字证书后,如何来对证书进行认证呢?
首先,会读取证书中的明文内容。CA 进行数字证书的签名时会保存一个 Hash 函数,来这个函数来计算明文内容得到信息A,然后用公钥解密明文内容得到信息B,两份信息做比对,一致则表示认证合法。
当然有时候对于浏览器而言,它不知道哪些 CA 是值得信任的,因此会继续查找 CA 的上级 CA,以同样的信息比对方式验证上级 CA 的合法性。一般根级的 CA 会内置在操作系统当中,当然如果向上找没有找到根级的 CA,那么将被视为不合法。
4.https过程
具体过程:
5. TLS1.2 握手的过程是怎样的
SSL 即安全套接层(Secure Sockets Layer),在 OSI 七层模型中处于会话层(第 5 层)。之前 SSL 出过三个大版本,当它发展到第三个大版本的时候才被标准化,成为 TLS(传输层安全,Transport Layer Security),并被当做 TLS1.0 的版本,准确地说,TLS1.0 = SSL3.1。
传统 https握手(即RSA版本)
之所以称它为 RSA 版本,是因为它在加解密pre_random的时候采用的是 RSA 算法。
1.浏览器向服务器发送client_random和加密方法列表。
2.服务器接收到,返回server_random、密码套件(RSA等)以及公钥。
3.浏览器接收,接着生成另一个随机数pre_random, 并且用公钥加密,传给服务器。(敲黑板!重点操作!)
4.服务器用公钥解密这个被加密后的pre_random。
现在浏览器和服务器有三样相同的凭证:client_random、server_random和pre_random。然后两者用相同的加密方法混合这三个随机数,生成最终的密钥。然后浏览器和服务器尽管用一样的密钥进行通信,即使用对称加密。
TLS 1.2 握手过程
下面的这张图简要地描述了 TLS 的握手过程,其中每一个“框”都是一个记录,多个记录组合成一个 TCP 包发送。所以,最多经过两次消息往返(4 个消息)就可以完成握手,然后就可以在安全的通信环境里发送 HTTP 报文,实现 HTTPS 协议。
下面我就用这个图来仔细剖析 TLS 的握手过程:
- 1.Client Hello:里面有客户端的版本号、支持的密码套件,还有一个随机数(Client Random),用于后续生成会话密钥。
- 2.Server Hello:把版本号对一下,也给出一个随机数(Server Random),然后从客户端的列表里选一个作为本次通信使用的密码套件。例如:
TLS_ECDHE_WITH_AES_128_GCM_SHA256
意思是TLS握手过程中,使用ECDHE算法生成pre_random(这个数后面会介绍),128位的AES算法进行对称加密,在对称加密的过程中使用主流的GCM分组模式,因为对称加密中很重要的一个问题就是如何分组。最后一个是哈希摘要算法,采用SHA256算法。
其中值得解释一下的是这个哈希摘要算法,试想一个这样的场景,服务端现在给客户端发消息来了,客户端并不知道此时的消息到底是服务端发的,还是中间人伪造的消息呢?现在引入这个哈希摘要算法,将服务端的证书信息通过这个算法生成一个摘要(可以理解为比较短的字符串),用来标识这个服务端的身份,用私钥加密后把加密后的标识和自己的公钥传给客户端。客户端拿到这个公钥来解密,生成另外一份摘要两个摘要进行对比,如果相同则能确认服务端的身份。这也就是所谓数字签名的原理。其中除了哈希算法,最重要的过程是私钥加密,公钥解密。
- 3.Server Certificate
服务器为了证明自己的身份,就把证书也发给了客户端。(证书里面里有公钥) - 4.Server Key Exchange
接下来是一个关键的操作,因为服务器选择了 ECDHE(其中一个算法) 算法,所以它会在证书后发送“Server Key Exchange”消息,里面是椭圆曲线的公钥(Server Params),用来实现密钥交换算法,再加上自己的私钥签名认证。 - 5.Server Hello Done
这样第一个消息往返就结束了(两个 TCP 包),结果是客户端和服务器通过明文共享了 三个信息:Client Random、Server Random 和 Server Params。
此时客户端这时也拿到了服务器的证书,那这个证书是不是真实有效的呢?就验证证书有效性和确认服务器身份。(认证方式看上面 认证过程)
- 6.Client Key Exchange
客户端按照密码套件的要求,也生成一个椭圆曲线的公钥(Client Params),用“Client Key Exchange”消息发给服务器。
现在客户端和服务器手里都拿到了密钥交换算法的两个参数(Client Params、Server Params),就用 ECDHE 算法一阵算,算出了一个新的东西,叫“Pre-Master”,其实也是一个随机数。
现在客户端和服务器手里有了三个随机数:Client Random、Server Random 和 Pre-Master。用这三个作为原始材料,就可以生成用于加密会 话的主密钥,叫“Master Secret”。而黑客因为拿不到“Pre-Master”,所以也就得不到主密钥。
为什么非得这么麻烦,非要三个随机数呢?
这就必须说 TLS 的设计者考虑得非常周到了,他们不信任客户端或服务器伪随机数的可靠性,为了保证真正的“完全随机”“不可预测”,把三个不可靠的随机数混合起来,那么“随机”的程度就非常高了,足够让黑客难以猜测。
- 7.Change Cipher Spec
- 该报文提示服务器,在此报文之后的通信会采用Pre-master -secret密钥加密
- 8.Finished
该报文包含连接至今全部报文的整体校验值。这次握手协商能否成功,要以服务器是否能够正确解密该报文作为判断依据。 - 9.Change Cipher Spec
- 10.Finshed
服务器也是同样的操作,发“Change Cipher Spec”和“Finished”消息,双方都验证加密解密 OK,握手正式结束,后面就收发被加密的 HTTP 请求和响应了。
与传统的握手有两点不同:
- 第一个,使用 ECDHE 实现密钥交换,而不是 RSA,所以会在服务器端发出“Server Key Exchange”消息。
- 第二个,因为使用了 ECDHE,客户端可以不用等到服务器发回“Finished”确认握手完毕,立即就发出 HTTP 报文,省去了一个消息往返的时间浪费。这个叫“TLS False Start”,意思就是“抢跑”,和“TCP Fast Open”有点像,都是不等连接完全建立就提前发应用数据,提高传输的效率。
双向认证的流程
不过上面说的是“单向认证”握手过程,只认证了服务器的身份,而没有认证客户端的身份。这是因为通常单向认证通过后已经建立了安全通信,用账号、密码等简单的手段就能够确认用户的真实身份。 但为了防止账号、密码被盗,有的时候(比如网上银行)还会使用 U 盾给用户颁发客户端证书,实现“双向认证”,这样会更加安全。
双向认证的流程也没有太多变化,只是在“Server Hello Done”之后,“Client Key Exchange”之前,客户端要发送“Client Certificate”消息,服务器收到后也把证书链走一遍,验证客户端的身份。
6.TLS1.3改进了 什么
对于TLS1.2做了一系列的改进,主要分为这几个部分:强化安全、提高性能。
强化安全:
在 TLS1.3 中废除了非常多的加密算法,最后只保留五个加密套件:
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_GCM_SHA256
- TLS_AES_128_GCM_8_SHA256
可以看到,最后剩下的对称加密算法只有 AES 和 CHACHA20,之前主流的也会这两种。分组模式也只剩下 GCM 和 POLY1305, 哈希摘要算法只剩下了 SHA256 和 SHA384 了。
之前RSA这么重要的非对称加密算法怎么不在了?
1.2015年发现了FREAK攻击,即已经有人发现了 RSA 的漏洞,能够进行破解了。
2.RSA 做密钥交换,这是因为它不具有“前向安全”(Forward Secrecy)。
假设有这么一个很有耐心的黑客,一直在长期收集混合加密系统收发的所有报文。如果加密系统使用服务器证书里的 RSA 做密钥交换,一旦私钥泄露或被破解(使用社会工程学或者巨型计算机),那么黑客就能够使用私钥解密出之前所有报文的“Pre-Master”,再算出会话密钥,破解所有密文。
这就是所谓的“今日截获,明日破解”。 而 ECDHE 算法在每次握手时都会生成一对临时的公钥和私钥,每次通信的密钥对都是不同的,也就是“一次一密”,即使黑客花大力气破解了这一次的会话密钥,也只是这次通信被攻击,之前的历史消息不会受到影响,仍然是安全的。
提升性能
- 1-RTT握手
其实具体的做法还是利用了扩展。客户端在“Client Hello”消息里直接用“supported_groups”带上支持的曲线,比如 P-256、x25519,用“key_share”带上曲线对应的客户端公钥参数,用“signature_algorithms”带上签名算法。服务器收到后在这些扩展里选定一个曲线和参数,再用“key_share”扩展返回服务器这边的公钥参数,就实现了双方的密钥交换,后面的流程就和 1.2 基本一样了。
- 会话复用
会话复用有两种方式: Session ID和Session Ticket。
先说说最早出现的Seesion ID,具体做法是客户端和服务器首次连接后各自保存会话的 ID,并存储会话密钥,当再次连接时,客户端发送ID过来,服务器查找这个 ID 是否存在,如果找到了就直接复用之前的会话状态,会话密钥不用重新生成,直接用原来的那份。
但这种方式也存在一个弊端,就是当客户端数量庞大的时候,对服务端的存储压力非常大。
因而出现了第二种方式——Session Ticket。它的思路就是: 服务端的压力大,那就把压力分摊给客户端呗。具体来说,双方连接成功后,服务器加密会话信息,用Session Ticket消息发给客户端,让客户端保存下来。下次重连的时候,就把这个 Ticket 进行解密,验证它过没过期,如果没过期那就直接恢复之前的会话状态。
这种方式虽然减小了服务端的存储压力,但与带来了安全问题,即每次用一个固定的密钥来解密 Ticket 数据,一旦黑客拿到这个密钥,之前所有的历史记录也被破解了。因此为了尽量避免这样的问题,密钥需要定期进行更换。
总的来说,这些会话复用的技术在保证1-RTT的同时,也节省了生成会话密钥这些算法所消耗的时间,是一笔可观的性能提升。
- PSK
刚刚说的都是1-RTT情况下的优化,那能不能优化到0-RTT呢?
答案是可以的。做法其实也很简单,在发送Session Ticket的同时带上应用数据,不用等到服务端确认,这种方式被称为Pre-Shared Key,即 PSK。
这种方式虽然方便,但也带来了安全问题。中间人截获PSK的数据,不断向服务器重复发,类似于 TCP 第一次握手携带数据,增加了服务器被攻击的风险
总结:
TLS1.3 在 TLS1.2 的基础上废除了大量的算法,提升了安全性。同时利用会话复用节省了重新生成密钥的时间,利用 PSK 做到了0-RTT连接。
参考:
信任始于握手:TLS1.2连接过程解析