“握手”是建立一个HTTPS连接过程的专业术语。涉及SSL/TLS的大部分困难工作都在此步完成。
一个HTTPS连接涉及两方:客户端(发起连接的一方,通常是你的浏览器)和服务器。另一方就是“握手”的人。SSL握手的目的是实施一个安全连接所需的所有加密工作。这包括SSL证书使用的验证以及生成一个密钥。
由于达成这一目的的每一个步骤所用到的软件都是不同的,握手的第一步就是让客户端和服务器共用彼此的性能,以发现他们共同支持的加密功能。浏览器是最常见的客户端,而诸如Chrome、火狐、IE等不同浏览器的功能也互不相同。类似地,在服务器端,诸如Windows Server、Apache、NGINX等常见操作系统也有着不同的性能支持。
一旦客户端和服务器在他们使用的具体加密方法上达成一致,服务器就会向客户端发送它的SSL证书。客户端会检验以确认证书是“可信的”,这是一个极其重要的步骤。为真正建立一个安全连接,你不能只是加密你的数据,还要确保数据被发送到正确的人或地点。SSL证书提供了这种保证。
SSL证书是由证书颁发机构(CA)创建并签发的,这种机构是被批准颁发证书的公司。你可能知道其中一些比较著名的机构,如 Symantec和Comodo。CA遵守行业标准,确保你只能得到你真正拥有的网站或公司的证书。
在握手期间,客户端将进行加密安全检验来确保服务器提供的证书是可信的。这包括检验数字签名并确保证书来自于一个可信的CA。
客户端也会得到服务器拥有与此证书相关的私钥的证明。所有SSL证书都包含一对密钥,密匙由一个公钥和一个私钥组成。公钥用于加密数据,私钥则用于解密。这称为“不对称”加密,因为两个功能由不同的密钥来执行。
就最常见的密钥类型RSA来说,客户端会以公钥加密随机数据,用该公钥生成会话密钥。只有当服务器有私钥提供所有权证明的情况下,才能解密并使用该数据。如果使用另一类型的密钥,这个过程就变了,但总是需要检验所有权证明的。
握手的最后一部分涉及创建“会话密钥”,这实际上是用于安全通信的密钥。会话密钥是“对称”的,也就是说相同的密钥既用于加密也用于解密。这样的密钥能实现强加密性,其有效性大大超过不对称密钥,这使得它们适于在HTTPS连接中来回发送数据。
为结束握手,每一方都要使对方知道他们完成了所有必要的工作,然后双方都进行检验以确保握手过程中没有任何恶意篡改和破坏。整个握手发生在几百毫秒时间内。它是HTTPS连接中必须发生的第一件事,甚至要早于网页的加载。
一旦握手完成,已加密和验证过的HTTPS连接就开始了,所有在你和服务器之间被发送和接收的数据都受到保护。每次你重新访问一个网站的时候,握手都将重复发生。为了实现更高的效率和速度,很多服务器会执行一个“继续”过程。
握手包含一系列步骤,完成三个主要任务,我们将其概括为:交换加密功能、验证SSL证书和交换/生成会话密钥。希望了解具体过程的读者请看备注[1]。注意,在即将到来的TLS1.3中,握手设计发生了变化,因此这些步骤不适用于TLS1.3。
下图阐释了这些步骤,左侧是客户端,右侧是服务器。[2]每一步都有箭头标识出接收消息的一方。
第一个消息是“客户端问候”,是发送给服务器的。这条消息展示出客户端具备的性能,这样服务器就可以选择怎样进行通信。
服务器以“服务器问候”消息作回应。这条消息,告知了客户端它从列表中选择的连接参数。如果客户端和服务器不具备任何共同的性能,连接就将被终止。
在“证书”消息中,服务器发送它的SSL证书链(包括它的叶子证书和中间证书)到客户端。与加密同样重要的是,为向连接提供验证,一个SSL证书要由一个能够使客户端验证证书合法性的CA签发。然后客户端将执行检验以确保证书合法。[3]这包括检验证书的数字签名、验证证书链以及对任何可能存在问题(如证书过期、域名错误等)的证书数据的检验。客户端也会确保服务器有证书私钥的所有权。这是在密钥交换/生成过程中完成的。
这是一个可选消息,只有某些要求服务器提供额外数据的密钥交换方法才需要。
“服务器问候完成”消息告知客户端它的所有消息发送完毕。
客户端也对会话密钥有帮助。这一步的细节取决于在初始“问候”消息中就已确定的密钥交换方法。TLS使用两种不同密钥:一个公钥/私钥对(SSL证书的一部分)和一个握手期间生成的会话密钥。会话密钥是“对称密钥”。它是在HTTPS连接期间使用的密钥,因为相比天然较慢的“不对称”的公钥/私钥对,它明显更快、更高效。公钥/私钥对只在会话密钥的安全传输的这几个步骤中使用。
“更换密码规范”消息使另一方知道它生成了会话密钥并要转换到加密通信。
然后发送“完成”消息,说明握手已经完成。该消息是加密的,而且是被会话密钥保护的第一个数据。该消息包含允许双方确认握手未被篡改的数据。
现在到了服务器做相同事情的时候了,服务器发送它的“更换密码规范”消息,表示它要转换到加密通信。
服务器发送“完成”消息。
在这几步完成后,SSL握手就完成了。双方现在有了一个会话密钥并开始以一个加密的和验证过的连接进行通信。从这时起,“应用”数据(属于实际服务的数据,也就是网站的HTML、Javascript等)的第一个字节可以被发送了。
备注:
[1]注意我们只是在讲一个只涉及服务器验证的典型的握手。在TLS中,可能会有互相验证,客户端也会提供证书。但很少使用。
[2]参考文献:Section 7 & 7.4 of the TLS 1.2 RFC. Chapter 2 of Bulletproof SSL & TLS by Ivan Ristic
[3]注意,TLS的RFC规定证书验证应在“服务器问候完成”消息之后进行。