Skip to content

55.3. SASL 认证#

55.3.1. SCRAM-SHA-256 认证

SASL是面向连接协议的认证框架。目前,PostgreSQL实现了两种 SASL 认证机制,即 SCRAM-SHA-256 和 SCRAM-SHA-256-PLUS。未来可能会添加更多机制。以下步骤说明了 SASL 认证的常规执行方式,而下一小节将详细介绍 SCRAM-SHA-256 和 SCRAM-SHA-256-PLUS。

SASL 认证消息流

  1. 为了开始 SASL 认证交换,服务器会发送 AuthenticationSASL 消息。其中包含服务器可以接受的 SASL 认证机制列表,按服务器的首选顺序排列。

  2. 客户端从列表中选择一种受支持的机制,并向服务器发送 SASLInitialResponse 消息。该消息包括所选机制的名称,以及可选的初始客户端响应(如果所选机制使用该响应)。

  3. 接下来将出现一个或多个服务器质询和客户端响应消息。每个服务器质询都通过 AuthenticationSASLContinue 消息发送,然后是客户端在 SASLResponse 消息中的响应。消息的具体内容取决于机制。

  4. 最后,当身份验证交换成功完成后,服务器将发送 AuthenticationSASLFinal 消息,然后立即发送 AuthenticationOk 消息。AuthenticationSASLFinal 包含其他服务器到客户端数据,其内容特定于所选身份验证机制。如果身份验证机制不使用在完成时发送的其他数据,则不会发送 AuthenticationSASLFinal 消息。

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

55.3.1. SCRAM-SHA-256 身份验证#

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

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

SCRAM 规范规定密码也采用 UTF-8,并使用SASLprep算法进行处理。PostgreSQL然而不要求对密码使用 UTF-8。当设置用户的密码时,无论使用何种实际编码,都将其视为 UTF-8 使用 SASLprep 进行处理。但是,如果它不是合法的 UTF-8 字节序列,或者它包含 SASLprep 算法禁止的 UTF-8 字节序列,则将使用原始密码而不进行 SASLprep 处理,而不是引发错误。这允许在 UTF-8 中对密码进行规范化,但仍允许使用非 UTF-8 密码,并且不要求系统知道密码的编码。

在具有 SSL 支持的 PostgreSQL 构建中支持通道绑定。具有通道绑定的 SCRAM 的 SASL 机制名称是SCRAM-SHA-256-PLUS。PostgreSQL 使用的通道绑定类型是tls-server-end-point

在没有通道绑定的SCRAM中,服务器选择一个随机数,将其传输给客户端,与传输的密码哈希中的用户提供的密码混合。虽然这可以防止密码哈希在以后的会话中成功重新传输,但它并不能阻止真正的服务器和客户端之间的虚假服务器传递服务器的随机值并成功进行身份验证。

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

示例

  1. 服务器发送 AuthenticationSASL 消息。它包括服务器可以接受的 SASL 身份验证机制列表。如果服务器内置 SSL 支持,则为 SCRAM-SHA-256-PLUSSCRAM-SHA-256,否则仅为后者。

  2. 客户端通过发送 SASLInitialResponse 消息进行响应,该消息指示所选机制 SCRAM-SHA-256SCRAM-SHA-256-PLUS。(客户端可以自由选择任一机制,但为了更好的安全性,如果它可以支持,它应该选择通道绑定变体。)在初始客户端响应字段中,消息包含 SCRAM client-first-messageclient-first-message 还包含客户端选择的通道绑定类型。

  3. 服务器发送 AuthenticationSASLContinue 消息,其中 SCRAM server-first-message 作为内容。

  4. 客户端发送 SASLResponse 消息,其中 SCRAM client-final-message 作为内容。

  5. 服务器发送 AuthenticationSASLFinal 消息,其中 SCRAM server-final-message,然后立即发送 AuthenticationOk 消息。