53.3. SASL 验证

  • SASL *是用于面向连接的协议中的身份验证的框架。目前,PostgreSQL 实现了两种 SASL 身份验证机制,即 SCRAM-SHA-256 和 SCRAM-SHA-256-PLUS。将来可能会添加更多。以下步骤说明了一般情况下如何执行 SASL 身份验证,而下一个小节将提供有关 SCRAM-SHA-256 和 SCRAM-SHA-256-PLUS 的更多详细信息。

SASL 验证消息流

  • 要开始 SASL 身份验证交换,服务器将发送 AuthenticationSASL 消息。它包括服务器可以接受的 SASL 身份验证机制的列表,并按照服务器的首选 Sequences。
  • Client 端从列表中选择一种受支持的机制,然后向服务器发送 SASLInitialResponse 消息。该消息包括所选机制的名称,以及可选的初始 Client 端响应(如果所选机制使用的名称)。
  • 随后将出现一个或多个服务器质询和 Client 端响应消息。在 AuthenticationSASLContinue 消息中发送每个服务器质询,然后在 SASLResponse 消息中来自 Client 端的响应。消息的细节是特定于机制的。
  • 最后,当成功完成身份验证交换后,服务器将发送 AuthenticationSASLFinal 消息,然后立即发送 AuthenticationOk 消息。 AuthenticationSASLFinal 包含其他服务器到 Client 端数据,其内容特定于所选的身份验证机制。如果身份验证机制不使用完成时发送的其他数据,则不会发送 AuthenticationSASLFinal 消息。

出现错误时,服务器可以在任何阶段中止身份验证,并发送 ErrorMessage。

53 .3.1. SCRAM-SHA-256 身份验证

目前已实现的 SASL 机制为SCRAM-SHA-256及其带有通道绑定SCRAM-SHA-256-PLUS的变体。在 RFC 7677 和 RFC 5802 中对它们进行了详细描述。

在 PostgreSQL 中使用 SCRAM-SHA-256 时,服务器将忽略 Client 端在client-first-message中发送的用户名。而是使用已经在启动消息中发送的用户名。 PostgreSQL 支持多种字符编码,而 SCRAM 规定将 UTF-8 用作用户名,因此可能无法用 UTF-8 表示 PostgreSQL 用户名。

SCRAM 规范规定该密码也是 UTF-8,并且使用* SASLprep *算法进行处理。但是,PostgreSQL 不需要使用 UTF-8 作为密码。设置用户密码后,无论使用哪种实际编码,都将使用 SASLprep 对其进行处理,就像使用 UTF-8 一样。但是,如果它不是合法的 UTF-8 字节序列,或者包含 SASLprep 算法禁止的 UTF-8 字节序列,则将使用原始密码而不进行 SASLprep 处理,而不会引发错误。这样可以使密码在 UTF-8 中时被规范化,但是仍然允许使用非 UTF-8 密码,并且不需要系统知道密码的 encodings。

带有 SSL 支持的 PostgreSQL 版本支持通道绑定。具有通道绑定的 SCRAM 的 SASL 机制名称为SCRAM-SHA-256-PLUS。 PostgreSQL 使用的通道绑定类型是tls-server-end-point

在没有通道绑定的 SCRAM 中,服务器选择一个随机数,该随机数将被发送到 Client 端,并与发送的密码哈希中的用户提供的密码混合。虽然这可以防止密码哈希在以后的会话中成功重传,但不能防止真实服务器和 Client 端之间的伪造服务器通过服务器的随机值并成功进行身份验证。

带有通道绑定的 SCRAM 通过将服务器证书的签名混合到传输的密码哈希中来防止这种中间人攻击。虽然伪造的服务器可以重新传输真实服务器的证书,但它无权访问与该证书匹配的私钥,因此无法证明它是所有者,从而导致 SSL 连接失败。

Example

  • 服务器发送 AuthenticationSASL 消息。它包括服务器可以接受的 SASL 身份验证机制的列表。如果服务器是使用 SSL 支持构建的,则将是SCRAM-SHA-256-PLUSSCRAM-SHA-256,否则将是后者。
  • Client 端通过发送 SASLInitialResponse 消息进行响应,该消息指示所选的机制SCRAM-SHA-256SCRAM-SHA-256-PLUS。 (Client 端可以自由选择任何一种机制,但是为了获得更好的安全性,如果它可以支持它,则应该选择通道绑定变体.)在“初始 Client 端响应”字段中,消息包含 SCRAM client-first-messageclient-first-message还包含 Client 端选择的通道绑定类型。
  • 服务器发送 AuthenticationSASLContinue 消息,内容为 SCRAM server-first-message
  • Client 端发送 SASLResponse 消息,内容为 SCRAM client-final-message
  • 服务器发送带有 SCRAM server-final-message的 AuthenticationSASLFinal 消息,紧接着是 AuthenticationOk 消息。