HTTPS 运行机制
HTTPS 确保了客户和服务器之间通信的安全性,具体来说,这种安全性主要包括机密性、完整性和端点鉴别。
信息安全三要素
信息安全三要素即机密性(Confidentiality)、完整性(Integrity)和可用性(Availability),简称 CIA。
- 机密性:仅有发送方和希望的接收方能够理解传输报文的内容。因为窃听者可以截获报文,这必须要求报文在一定程度上进行 加密(encrypted),使截取的报文无法被截获者所理解。机密性的这个方面大概就是通常意义上对于术语 信息安全 的理解。
- 完整性:或称 报文完整性 或 报文鉴别,即通信双方希望确保其通信的内容在传输过程中未被改变 —— 或者恶意篡改或者意外改动。我们在可靠数据传输和数据链路协议中遇到的 检验和 技术在扩展后能够用于提供这种报文完整性。
- 可用性:指保证信息确实能为授权使用者所用,即保证合法用户在需要时可以使用所需信息。
除了 CIA 之外,还有一点需要注意,即端点鉴别(end-point authentication),这是指发送方和接收方都应该能证实通信过程所涉及的另一方,以确信通信的另一方确实具有其所声称的身份。
报文鉴别码
通过报文鉴别码可以实现完整性,具体而言,A 和 B 需要共享秘密比特串 $s$,它被称为鉴别密钥(authentication key)。使用这个共享秘密,报文完整性能够执行如下:
- A 生成报文 $m$,用 $s$ 级联 $m$ 以生成 $m+s$,并计算哈希 $H(m+s)$(例如使用 SHA-1)。$H(m+s)$ 被称为报文鉴别码(Message Authentication Code,MAC)。
- 然后 A 将 MAC 附加到报文 $m$ 上,生成扩展报文 $(m, H(m+s))$,并将该扩展报文发送给 B。
- B 接收到一个扩展报文 $(m, h)$,由于知道 $s$,计算出报文鉴别码 $H(m+s)$。若 $H(m+s)=h$,则一切正常。
MAC 的一个优良特点是它不要求一种加密算法,多年来已经提出了若干种对 MAC 的不同标准,目前最为流行的标准是 HMAC,它能够与 MD5 或 SHA-1 一道使用。
其实使用数字签名也可以实现完整性,同时也验证了该报文的源(注意 MAC 并不能做到这一点)。具体使用 MAC 还是数字签名实现完整性,在不同的协议里有不同的选择,如 PGP 使用数字签名,而 OSPF 和 SSL 使用 MAC。
在生成 MAC 过程中既不涉及公开密钥加密,也不涉及对称密钥加密。而在生成数字签名的过程中涉及到了公开密钥加密,因此,数字签名是一种“技术含量更高”的技术,因为它需要一个如后面描述的、具有认证中心支撑的公钥基础设施(PKI)。
公钥认证
公钥认证(public key certification)即证实一个公钥属于某个特定的实体。将公钥与特定实体绑定通常是由认证中心(Certification Authority,CA)完成的,CA 的职责就是使识别和发行证书合法化。CA 具有下列作用:
- CA 证实一个实体(一个人、一台路由器等)的真实身份。
- 一旦 CA 验证了某个实体的身份,这个 CA 会生成一个将其身份和实体的公钥绑定起来的证书(certificate)。这个证书包含这个公钥和公钥所有者全局唯一的身份标识信息(例如,一个人的名字或一个 IP 地址)。由 CA 对这个证书进行数字签名。
端点鉴别
鉴别应当在报文和数据交换的基础上,作为某 鉴别协议(authentication protocol)的一部分独立完成。鉴别协议通常在两个通信实体运行其他协议 之前 运行。鉴别协议首先建立相互满意的各方标识;仅当鉴别完成之后,各方才继续下面的工作。
一个实际可行的鉴别协议会使用到 对称密钥 和 不重数,不重数(nonce)是在一个协议的生存期中只使用一次的数,也就是说,一旦某协议使用了一个不重数,就永远不会再使用那个数字了。具体过程如下所示:
- A 向 B 发送报文“我是 A”
- B 选择一个不重数 $R$,然后把这个值发送给 A
- A 使用它与 B 共享的对称密钥 $K_{A-B}$ 来加密这个不重数,然后把加密的不重数 $K_{A-B}(R)$ 发回给 B。
- B 解密接收到的报文。若解密得到的不重数等于它发送给 A 的那个不重数,则可鉴别 A 的身份。
使用对称密钥确保了鉴别的双方,而使用不重数则预防了回放攻击(playback attack)。
对于 HTTPS 而言,端点鉴别具体分为:服务器鉴别 和 客户鉴别。服务器鉴别是为了防止站点假冒(这可以通过 CA 证书来验证),客户鉴别是为了防御连接重放。
SSL 与 TLS
SSL(Secure Socket Layer,安全套接字层)最初由 Netscape 设计,其发展到现在存在一些设计上的漏洞,SSL 版本 3 的一个稍加修改的版本被称为 TLS(Transport Layer Security,传输层安全性)。
现在为了安全性基本都采用 TLS,本文以下内容采用 SSL 来指代最新的 TLS。
SSL 经常用来为发生在 HTTP 之上的事务提供安全性。然而,因为 SSL 使 TCP 安全了,因此它能被应用于运行在 TCP 之上的任何应用程序。
SSL 工作过程
SSL 具有三个阶段:握手、密钥导出和数据传输:
握手
SSL 握手步骤如下:
- 客户发送它支持的密码算法的列表(cipher suit),连同一个客户的不重数。
- 从该列表中,服务器选择一种对称算法(例如 AES)、一种公钥算法(例如具有特定密钥长度的 RSA)和一种 MAC 算法(即哈希算法)。它把它的选择以及证书和一个服务器不重数返回给客户。
- 客户验证该证书,提取服务器的公钥,生成一个前主密钥(Pre-Master Secret,PMS),用服务器的公钥加密该 PMS,并将加密的 PMS 发送给服务器。
- 使用相同的密钥导出函数(就像 SSL 标准定义的那样),客户和服务器独立地从 PMS 和不重数中计算出主密钥(Master Secret,MS)。然后该 MS 被切片以生成两个密码和两个 MAC 密钥。此外,当选择的对称密码应用于 CBC(例如 3DES 或 AES),则两个初始向量(IV)也从该 MS 获得,这两个 IV 分别用于该连接的两端。自此以后,客户和服务器之间发送的所有报文均被加密和鉴别(使用 MAC)。具体可见下节密钥导出。
- 客户发送所有握手报文的一个 MAC。
- 服务器发送所有握手报文的一个 MAC。
最后两个步骤使握手免受篡改危害。
密钥导出
客户和服务器都使用 MS 生成 4 个密钥:
- $E_C$:用于从客户(C)发送到服务器(S)的数据的会话加密密钥(用于机密性)
- $M_C$:用于从客户(C)发送到服务器(S)的数据的会话 MAC 密钥(用于完整性)
- $E_S$:用于从服务器(S)发送到客户(C)的数据的会话加密密钥(用于机密性)
- $M_S$:用于从服务器(S)发送到客户(C)的数据的会话 MAC 密钥(用于完整性)
数据传输
由于 TCP 是一种字节流协议,SSL 将数据流分割成 记录,对每个记录附加一个 MAC 用于完整性检查,然后加密该“记录+MAC”。为了产生这个 MAC,客户将数据连同密钥 $M_C$ 放入一个散列函数中;为了加密“记录+MAC”这个包,客户使用它的会话加密密钥 $E_C$。然后这个加密的包将传递给 TCP 经因特网传输。
为了防止诸如重排序或重放报文段等中间人攻击,SSL 使用序号,具体而言,客户维护一个序号计数器,计数器开始为 0,客户每发送的一个 SSL 记录它都增加 1。客户并不实际在记录中包括一个序号,但当它计算 MAC 时,它把该序号包括在 MAC 的计算中。所以,该 MAC 现在是数据加 MAC 密钥 $M_C$ 加 当前序号 的哈希值。服务器跟踪客户的序号,通过在 MAC 的计算中包括适当的序号,使它验证一条记录的数据完整性。
总而言之,在 SSL 中,不重数用于防御“连接重复”,而序号用于防御在一个进行中的会话中重放个别分组。
一个 SSL 记录如下图所示:
该记录由类型字段、版本字段、长度字段、数据字段和 MAC 字段组成。注意到前 3 个字段是不加密的。类型字段指出了该字段是握手报文还是包含应用数据的报文。它也用于关闭 SSL 连接,如下面所讨论。在接收端的 SSL 使用长度字段以从到达的 TCP 字节流中提取 SSL 记录。版本字段是自解释的。