标签归档:RSA

HTTPS 与互联网可信、安全连接机制概貌

由于互联网开放的特性,在网络中传送的信息十分容易在途中各个环节上被他人截获、窃取和篡改,这威胁到了在网络中传输的敏感数据的安全。HTTP 是目前互联网中应用最广泛的应用层协议,所有基于 Web 的应用和多数移动 App 都通过 HTTP 与服务器通信。之前的文章HTTP 协议概貌中提到,HTTP 是一个基于 TCP 的应用层协议,HTTP 传送的所有信息,包括 HTTP 头部在内都是不作任何处理直接交付给 TCP 来传输的,敏感信息在这个过程中可能被泄露,也可能被篡改而损害通信双方的利益。例如用户在通过输入用户名和密码登录一个 Web 站点时,浏览器向服务器提交的用户名和密码就可能被他人截获;在随后的正常浏览过程中,HTTP 头部中用于维持会话的 cookie 也可能被他人截获,直接威胁用户账号的安全。

为了解决 HTTP 传输数据安全的问题,网景公司最早在 1994 年推出了 HTTPS 协议。HTTPS 协议不直接使用 TCP 传送 HTTP 的数据流,而是在原有的 HTTP 与 TCP 之间加入了一层安全套接层(Secure Sockets Layer,SSL),浏览器与服务器双方都将 HTTP 的数据流先用非对称加密算法加密之后再交付给 TCP,双方的 SSL 收到数据后再通过相应的密钥将数据先解密,再交付给 HTTP 层解析。HTTPS 在互联网中传送的都是不能直接理解的密文,即使在传输过程中被他人截获,攻击者也几乎没有办法将截获的密文复原成原文,这样保证数据在传输过程中的安全。

对于互联网中 Web 站点的用户来说,除了信息在传输过程中可能被窃取之外,还有另一个潜在的安全威胁,那就是仿冒网站的问题。几乎所有的 Web 站点都是通过域名来访问的,如果攻击者通过 DNS 欺骗等手段将浏览器请求的域名解析到一个仿冒网站上,用户在不知情的情况下可能会向仿冒网站主动提交用户名密码等敏感信息。对于仿冒网站的问题,HTTPS 也有数字签名、数字证书等机制防止这种攻击发生,下文将讨论它们的原理。

互联网上对信息安全极为敏感的服务如网上银行等很早就使用 HTTPS 来保障传输数据的安全,许多其他大型网站为了安全,也在登录页上使用 HTTPS 保护用户的用户名和密码等。近期,国内外越来越多知名网站已经开始全站从 HTTP 升级到 HTTPS,HTTPS 化已经成为未来互联网的发展趋势。

1. SSL 与 TLS

SSL 最早是网景公司为了保证 HTTP 安全而设计的安全套接层,SSL 对上层的 HTTP 来说是透明的,因此也能在 SSL 上运行其他的应用层协议来给其他应用提供同样的安全保障。随后 IEFT 将 SSL 标准化,将其更名为传输层安全协议(Transport Layer Security,TLS),并于 1999 年公布了第一版 TLS 标准文件。后又公布了 RFC 5246(2008年8月)和 RFC 6176(2011年3月)。浏览器、电子邮件、即时通讯、VoIP 和网络传真等应用程序都广泛支持 TLS 协议[1]

SSL/TLS 的设计目标是通过一个不安全的网络通道在两个应用程序之间建立安全的连接,防止传输的信息被窃取和篡改。TLS 通过非对称密钥加密建立安全连接来协商和交换下一步对称加密用的算法和密钥,并在公钥基础设施(Public Key Infrastructure,PKI)的参与下通过数字证书实现可信的身份认证。关于非对称加密算法、数字证书和 PKI 等概念还将在下文中继续讨论。

TLS 连接的建立大致分为协商阶段、交换密钥和证书阶段以及基于对称密钥加密的保密传输阶段等。

1.1 协商阶段

建立 TLS 连接第一步就是客户端与服务端双方通过握手消息交换相互支持的协议版本、加密算法和压缩算法等信息,通过协商一致使用一种双方都支持的连接参数。在这个过程中,客户端先向服务端发送一个 ClientHello 消息,其中包含客户端所支持的 TLS 协议版本、密码套件列表、压缩方式、一个用于生成会话密钥的随机数以及扩展的其他信息(例如服务器名称、上层协议)等。下图展示了一个 TLS 连接建立过程中客户端向服务端发送的 ClientHello 消息的分析结果。

tls-client-hello图 1 对一个 TLS 连接阶段 ClientHello 消息的分析

服务端收到 ClientHello 后,根据自身的情况选择一组双方都支持的、最合适的参数,通过 ServerHello 确认给客户端,同样也会发送一个用于生成会话密钥的随机数。下图是对上述 TLS 连接过程中服务端响应给客户端的 ServerHello 的分析结果。

tls-server-hello图 2 对上述 TLS 连接阶段 ServerHello 消息的分析

1.2 交换证书和公钥阶段

进行一轮 ClientHello / ServerHello 握手之后,服务端会通过 Certificate 消息向客户端发送一个证书以证明自己的身份,同时证书里还包含一份公钥。如果双方协定 Diffie-Hellman 算法交换会话密钥,此时服务端还会发送一个 ServerKeyExchange 握手消息。如果采用的是双向认证方式,此时服务端还会发送 CertificateRequest 消息,请求客户端提供证书。最后服务端发送 ServerHelloDone 消息表示服务端结束握手消息。

客户端收到 ServerHelloDone 之后,如有必要,先通过 Certificate 消息发送自己的证书。随后通过 ClientKeyExchange 消息发送密钥。需要注意的是如果双方协定采用 Diffie-Hellman 算法交换会话密钥,此时这时传送的是未加密的客户端 DH Key;如果采用 RSA 交换密钥,此时传送的是经过服务端公钥加密的会话密钥。

接着客户端发送 ChangeCipherSpec 消息,这是客户端发出的最后一个明文消息,意味着从此客户端发出的数据均是经过会话密钥加密的信息。随后客户端发送第一个加密的消息:Finished。

服务端收到 Finished 之后,同样发送最后一个明文消息:ChangeCipherSpec,接着同样发送加密的 Finished。此时 TLS 最后一次握手完成,双方都通过加密的方式传送应用层数据,TLS 连接进入保密传输阶段。

1.3 保密传输阶段

这个阶段双方发送的消息均为 ApplicationData,其中运载的应用层数据是通过会话密钥加密的。

下面是从 RFC 5246[2] 中摘录的 TLS 连接握手的完整时序。

      Client                                               Server

      ClientHello                  -------->
                                                      ServerHello
                                                     Certificate*
                                               ServerKeyExchange*
                                              CertificateRequest*
                                  <--------       ServerHelloDone 
      Certificate*
      ClientKeyExchange 
      CertificateVerify* 
      [ChangeCipherSpec]
      Finished                    -------->
                                               [ChangeCipherSpec]
                                  <--------              Finished
      Application Data            <------->      Application Data

   * Indicates optional or situation-dependent messages that are not
   always sent.

2. 加密

在密码学中,加密是指将信息通过某种方式编码,使之只能被有授权的人读取。加密本身并不能阻止信息被截获,但加密过的信息内容对于攻击者来说是无意义的,只有相应密钥的持有者才能将加密过的信息还原成明文信息,这个过程称为解密。密钥是在加密算法中用于加密和解密的参数,通常是一个大的整数。有些加密算法使用同一个密钥加密和解密信息,另一些则使用不同的密钥,前者称为对称加密算法,后者称为公钥加密算法(或非对称加密算法)。这两种加密算法都在 TLS 中有应用。

2.1 对称加密算法

在前文提到的 TLS 连接中,在保密传输阶段 TLS 携带的应用层数据就是用一个会话密钥进行对称加密过的。对称加密又称为共享密钥加密,对称加密的密钥既能用于加密也能用于将密文解密成原文;在对称加密中,加密方和解密方共同使用同一个密钥进行加密和解密操作。常见的对称加密算法有 DES、3DES、AES、IDEA、RC5、RC6 等。

对称加密算法要求通信双方都拥有同一个密钥,并且密钥不能被第三者知道,因此双方如何安全地协商并交换密钥是一个需要解决的问题。Diffie-Hellman 是第一个实用的在非保护信道中建立共享信道的方法[3]。它的基本原理是通信双方各自生成一个随机数,然后通过一些运算将双方的随机数转换为两个公钥,并在非保护的通信信道中交换这两个公钥,然后双方都可以根据对方的公钥及自己的随机数计算出一个相同的公共密钥。并且这个算法保证了即使攻击者窃取了通信过程中交换的两个公钥,也极难计算出用于对称加密的公共密钥。本文不准备讨论 Diffie-Hellman 算法的具体数学原理,如有兴趣,可以参考维基百科 Diffie-Hellman 词条,这里有这个算法包括数学原理在内的更详细的细节。

另外,还可以先通过 RSA 等公钥加密机制来交换双方的共享密钥。TLS 支持用 Diffie-Hellman 算法交换共享密钥也支持用公钥加密机制交换共享密钥。

2.2 公钥加密算法

公钥加密算法也称为非对称加密算法,它的特征是一次生成一对密钥,一个只能用于加密,另一个只能用于解密,并且已知其中一个密钥无法推导出另一个密钥。在应用中,在非保护信道中公开将两个密钥的其中一个传送给对方,另一个自己保留。公开的那个密钥称为公钥,保留的密钥称为私钥。

当公开的是加密密钥时,这个算法可以用于建立单向的保密通信通道:收信者生成一对密钥,将加密密钥当作公钥发送给对方,对方用公钥加密信息,收信者用秘密的私钥解密得到原文。在这个过程中即使攻击者截获了用公钥加密的信息,但没有私钥就无法解密这些信息,信息的安全得到了保证。

当公开的是解密密钥时,加密密钥的持有者可以用手中的加密密钥对信息进行数字签名,公钥(解密密钥)的持有者可以通过解密对收到的信息进行确认,这样可以保障信息在传输过程中不受篡改和伪造,并确认信息发送者的身份。

公钥加密算法的上述两种应用场合都在 TLS 协议中有运用。同时,公钥加密算法还是数字证书机制的基础。最常见的一种公钥加密算法是 RSA 算法,维基百科 RSA 算法词条中有这种算法的详细数学原理。

3. 数字证书:数字身份认证机制

回顾前文中讨论的 TLS 连接建立过程,试想如果一个 TLS 连接使用 Diffie-Hellman 交换会话密钥,而在连接的交换密钥阶段服务端发送的 ServerKeyExchange 被一个第三方的攻击者劫持,这个攻击者再伪装成服务器向客户端发送它自己的 ServerKeyExchange,另一方面又伪装成客户端欺骗真正的服务器,这样一来似乎就构成了一次中间人攻击,攻击者可以在服务器和客户端之间伪装对方,窃取通信的信息。

然而上述的情形是不会发生的,TLS 具有身份认证的机制来防范中间人攻击。

3.1 数字签名

前文已经提到,在公钥加密算法中,如果公开解密密钥,那么信息发送者可以用加密密钥进行数字签名,接收者使用公钥进行确认,防止信息在传输过程中被伪造和篡改。在一份记载有文字信息的纸质文件上进行签名或者签章,代表签名者认可文件中所记载的内容,他人伪造的没有签名的文件和有修改痕迹的签名文件都会被认为是无效的。数字签名也是如此,一份附带有数字签名的电子信息文件,表示签名者认可这份电子信息的内容,并通过公开密钥加密算法保证这份文件无法伪造和被篡改,其他人都可以通过公钥来验证这份电子信息的真伪。

要进行数字签名,首先需要选定一种信息摘要算法。信息摘要算法是一种将任意长的信息不可逆地转换成较短的固定长度的信息的算法,常见的有 MD5、SHA-1、SHA-256 等算法。使用选定的信息摘要算法对要签名的文件计算一个摘要,然后用自己的私钥加密这个信息摘要,加密的结果就是对这份文件的数字签名。其他人收到这份文件后,先用相同的信息摘要算法对文件的正文求信息摘要,然后再用相应的公钥解密数字签名,将解密的结果与求得的信息摘要进行比对,如果两者一致则说明校验成功,这份文件是可信的;否则校验失败,说明这份文件可能是伪造的或者被篡改过的。

使用 Diffie-Hellman 交换会话密钥的 TLS 连接在交换密钥阶段,正是用数字签名的技术来防范中间人攻击的。在 1.2 节中提到在交换密钥阶段,服务端会先通过 Certificate 握手消息向客户端发送一个数字证书,数字证书中包含有一个公钥。在其后的 ServerKeyExchange 消息中,除了有交换的密钥信息之外,还有一个数字签名,客户端收到这个消息之后,使用服务端证书中的公钥来验证 ServerKeyExchange 消息是否可信。下面的图片展示了一个 ServerKeyExchange 消息的分析,可以看到其中有数字签名使用的算法、数字签名的长度和数字签名等几个字段。

tls-server-key-exchange图 3 TLS 连接过程中的一个 ServerKeyExchange 消息

3.2 数字证书与 PKI

在 3.1 小节中提到了服务端会向客户端发送一个 Certificate 消息,其中包含了一个数字证书,数字证书中有服务端的公钥。再考虑一下中间人攻击的手段,攻击者会不会先向客户端发送自己的证书,然后用自己的私钥签名 ServerKeyExchange 来欺骗客户端呢?答案是不行。数字证书之所以称为证书,是因为它是无法伪造的,攻击者如果自己发送一个假证书给客户端,客户端效验的时候就会发现它是伪造的,伪造的数字证书不会被信任。

数字证书无法伪造,是因为数字证书上有一个由数字证书认证机构(Certificate Authority,CA)签署的数字签名。数字证书上记载有服务器的域名和其他与服务器的身份相关的信息,以及一个验证数字签名用的公钥。当服务器管理员要为服务器申请一个数字证书时,必须将上述的材料提交给权威的数字证书认证机构审核,审核通过后会将申请中提交的信息填入数字证书,并用自己的私钥签上数字签名,表明该机构已核实证书中记载的全部信息。

CA 用于签发数字证书的私钥也对应一张证书,这张证书中的公钥用于验证该 CA 签发的数字证书的真伪。那么,CA 的数字证书又是由谁签发的呢?答案是由另一家更权威的机构签发的。这样,数字证书一级一级构成一个信任链,信任链的顶端就是根证书。根证书不由其他机构签发,它通常是通过预装在操作系统的“受信任的根证书存储区”中自动受到信任,根证书的私钥由相应的权威机构保管和控制。

上述的由软件、硬件、管理政策和机构组成的数字信任体系称为公钥基础设施(Public Key Infrastructure,PKI),建设公钥基础设施的目的在于创造、使用、管理、分配、存储和吊销数字证书[4]

3.3 数字证书的吊销机制

数字证书使用者必须妥善保管好用于签名的私钥,如果私钥被其他人盗取,攻击者就可以用盗来的私钥签署数字签名,冒充真正的数字证书持有者,这时候数字证书就失去了它应有的作用。好在 CA 签发的数字证书还有吊销的机制。CA 签发的数字证书中含有一个数字证书吊销列表(Certificate Revocation List,CRL)字段,该字段指向一个网络上的数字证书吊销列表,由证书的颁发者负责维护。当证书使用者发现自己的私钥可能被窃取时,就可以通知 CA 将该证书的序列号加入到证书吊销列表中。软件验证证书的时候也会检索证书吊销列表,如果发现证书的序列号在吊销列表中,则会认为该证书不可信。

但是根证书没有证书吊销列表也没有吊销机制,如果根证书的私钥发生泄密,则是非常严重的事故,攻击者可以利用窃取的根证书私钥签发假证书,将会危及整个体系的安全。历史上发生过 CA 泄露私钥的事故,处置危机的方案是各操作系统、浏览器等软件厂商发布补丁,把该 CA 的根证书从受信任的根证书列表中移除。另外历史上还有国内某家 CA 机构滥发假证书,事情败露后被各大操作系统和浏览器厂商从信任列表移除根证书的事件

参考文献
[1] Wikipedia. 传输层安全协议. https://zh.wikipedia.org/wiki/%E5%82%B3%E8%BC%B8%E5%B1%A4%E5%AE%89%E5%85%A8%E5%8D%94%E8%AD%B0
[2] T. Dierks, E. Rescorla, et al. The Transport Layer Security (TLS) Protocol Version 1.2, RFC 5246, Aug 2008; tools.ietf.org/html/rfc5246
[3] Wikipedia. 迪菲-赫爾曼密鑰交換. https://zh.wikipedia.org/wiki/%E8%BF%AA%E8%8F%B2-%E8%B5%AB%E7%88%BE%E6%9B%BC%E5%AF%86%E9%91%B0%E4%BA%A4%E6%8F%9B
[4] Wikipedia. 公開金鑰基礎建設. https://zh.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%87%91%E9%91%B0%E5%9F%BA%E7%A4%8E%E5%BB%BA%E8%A8%AD