在 SSL/TLS 中,数据包的哪一部分被加密和认证?

信息安全 tls
2021-08-16 05:59:32

我正试图围绕承载安全流量的应用程序数据记录。我了解 TLS/SSL 是一种“先验证后加密”协议,这意味着 HMAC 是通过纯文本计算的,并将生成的摘要附加到消息中。最后,使用协商的密码对整个数据包进行加密。

我也知道“应用程序数据”记录的前三个字段是:

  • 内容类型(0x17 表示应用程序数据)
  • 协议版本(TLS1.0 等的 0x0301)
  • 记录长度(加密内容的字节长度)

给定以下(简化的)“数据”

GET /index.html HTTP/1.1
Host: helpme.com

生成的加密数据包会是什么样子,哪些部分会被加密,哪些部分会被散列?

请使用以下(同样是简化的)插图使回答更容易:

01   |  ContentType  |  ProtocolVersion  |  RecordLength  |
02    GET /index.html HTTP/1.1
03    Host: helpme.com
04   |  HMAC  |  Padding  |

我阅读RFC 5246的最佳嘉宾:

第 01-03 行包含在 HMAC 中
第 02-04 行包含在加密中

任何帮助表示赞赏。

1个回答

简短的回答

在 HTTPS 的情况下,如果连接不安全,任何本应发送的数据都将作为加密的应用程序数据发送。此外,由于历史原因,MAC 和 Padding 也会被加密。在 SSL 3.0 和 TLS 1.0 中,这意味着布局将如下所示:

01 (plain)        |  ContentType  |  ProtocolVersion  |  RecordLength  |
02 (encrypted)    GET /index.html HTTP/1.1
03 (encrypted)    Host: helpme.com
04 (encrypted)    |  MAC  |  Padding  |

请注意,严格来说,MAC 只是 TLS 1.0 及更高版本中的 HMAC。在 SSL 3.0 中,它是一种仅在此协议中使用的特殊模式。

稍长的答案

从 TLS 1.1 开始,如果已协商 CBC 模式的分组密码,则会在加密数据的开头插入显式 IV:

01 (plain)        |  ContentType  |  ProtocolVersion  |  RecordLength  |
02                IV
03 (encrypted)    GET /index.html HTTP/1.1
04 (encrypted)    Host: helpme.com
05 (encrypted)    |  HMAC  |  Padding  |

IV 可以使密文变得不可预测并且不易受到某些密码攻击。在加密和解密时,实现可能会以不同的方式对待它。一些实现可能从随机生成它,而其他实现可能将它生成为前一个片段的最后一个块的密文,与一个常数值异或。相反,在解密时,实现可能将其视为独立字段或密文的第一个块(并在输出解密的纯文本片段之前丢弃相应的解密块,就像丢弃 HMAC 和填充一样)。

从 TLS 1.2 开始,可能会协商 AEAD 密码,这意味着 MAC 机制已集成到密码模式中,并且不需要 HMAC。在这种情况下,布局如下:

01 (plain)        |  ContentType  |  ProtocolVersion  |  RecordLength  |
02 (plain)        Nonce 
03 (encrypted)    GET /index.html HTTP/1.1
04 (encrypted)    Host: helpme.com

注意字段03和04对应的密文长度会比对应的明文长度长。确切的布局将取决于 AEAD 密码模式的细节。通常,它只会以 MAC 结束。

现在,更复杂的是,在所有协议版本和密码模式中,MAC 将根据与纯文本(可选压缩)片段和加密片段不同的数据进行计算。特别是,RecordLength 字段将具有纯文本/压缩值(不是加密值),并且将插入序列号以防止重放攻击。MAC 本身显然不包括在计算 MAC 的数据中,填充也不包括在内。最后一部分,MAC 没有通过填充计算,是一些针对 SSL/TLS 的攻击可能的原因。

隐式 SSL/显式 TLS

HTTPS 是Implicit SSL的一个实例,这大致意味着 SSL/TLS 将是连接的最外层协议层。通过连接发送的第一件事是 SSL/TLS 握手,所有应用程序数据都将加密发送。HTTPS 将始终是隐式 SSL。

相比之下,显式 TLS意味着 SSL/TLS 将作为底层应用程序协议的一部分进行显式协商。这在例如 SMTP、POP3 和 FTP 等应用协议的情况下很常见。当使用显式 TLS 时,通过连接发送的第一个数据将是应用程序协议的开放协议消息。

请注意,隐式 SSL 和显式 TLS 的“SSL”和“TLS”部分是用词不当,因为客户端和服务器完全有可能通过隐式 SSL 连接协商 TLS 1.0 或更高版本,反之则协商SSL 3.0 通过显式 TLS 连接。

可以信任客户端身份验证和会话恢复吗?

更复杂的是,应该记住,为某人加密某些东西并不能保证该实体将是唯一读取加密数据的人,因为永远不可能阻止接收者简单地将解密的纯文本转发给第三方派对。这在 SSL/TLS 的情况下尤其重要,因为身份验证通常只进行一种方式(服务器向客户端验证自身),并且需要特殊的握手来向服务器验证客户端。

该攻击演示了如何使用当前协议和一些密码原语来利用这一事实。但是,可以采取一些措施来防止这种情况发生。例如,以下规则将阻止攻击,但可能会破坏与现有实现的兼容性:

  1. 当服务器需要客户端身份验证时,可以:在初始握手完成后首先发送 hello_request 并请求第二次握手的客户端身份验证,或者 b。以这样的方式实现应用程序协议(或使用应用程序协议的应用程序),使得在客户端身份验证之前发送的任何数据都不会被客户端视为经过身份验证,例如通过在内部启动一个全新的应用程序会话并让客户端重新发送它发送的任何内容在经过身份验证的握手之前。
  2. 当通过恢复(缩写为握手)启动连接时,将该连接上的任何 hello_request 或 client_hello 消息视为错误。