Postgresql 中文操作指南
55.3. SASL Authentication #
SASL 是一个针对面向连接协议中的认证的框架。目前,PostgreSQL 实现了两种 SASL 认证机制,即 SCRAM-SHA-256 和 SCRAM-SHA-256-PLUS。将来可能还会添加更多。以下步骤说明了通常情况下 SASL 认证的执行方式,而下一小节将更详细地介绍 SCRAM-SHA-256 和 SCRAM-SHA-256-PLUS。
SASL is a framework for authentication in connection-oriented protocols. At the moment, PostgreSQL implements two SASL authentication mechanisms, SCRAM-SHA-256 and SCRAM-SHA-256-PLUS. More might be added in the future. The below steps illustrate how SASL authentication is performed in general, while the next subsection gives more details on SCRAM-SHA-256 and SCRAM-SHA-256-PLUS.
SASL Authentication Message Flow
如果发生错误,服务器可以在任何阶段中止认证,然后发送一个 ErrorMessage。
On error, the server can abort the authentication at any stage, and send an ErrorMessage.
55.3.1. SCRAM-SHA-256 Authentication #
The implemented SASL mechanisms at the moment are SCRAM-SHA-256 and its variant with channel binding SCRAM-SHA-256-PLUS. They are described in detail in RFC 7677 and RFC 5802.
当在 PostgreSQL 中使用 SCRAM-SHA-256 时,服务器会忽略客户端在 client-first-message 中发送的用户名。而是使用已在启动消息中发送的用户名。PostgreSQL 支持多种字符编码,而 SCRAM 规定用户名的编码应为 UTF-8,因此可能会无法以 UTF-8 表示 PostgreSQL 用户名。
When SCRAM-SHA-256 is used in PostgreSQL, the server will ignore the user name that the client sends in the client-first-message. The user name that was already sent in the startup message is used instead. PostgreSQL supports multiple character encodings, while SCRAM dictates UTF-8 to be used for the user name, so it might be impossible to represent the PostgreSQL user name in UTF-8.
SCRAM 规范规定密码也应为 UTF-8,并且使用 SASLprep 算法进行处理。但是,PostgreSQL 不要求密码使用 UTF-8。当设置用户的密码时,会将其按 UTF-8 进行 SASLprep 处理,无论实际使用的编码是什么。但是,如果它不是合法的 UTF-8 字节序列,或者它包含 SASLprep 算法禁止的 UTF-8 字节序列,那么会使用原始密码(不进行 SASLprep 处理),而不是抛出一个错误。这样一来,可以对 UTF-8 密码进行规范化,但仍然允许使用非 UTF-8 密码,并且无需系统知道密码采用的编码内容。
The SCRAM specification dictates that the password is also in UTF-8, and is processed with the SASLprep algorithm. PostgreSQL, however, does not require UTF-8 to be used for the password. When a user’s password is set, it is processed with SASLprep as if it was in UTF-8, regardless of the actual encoding used. However, if it is not a legal UTF-8 byte sequence, or it contains UTF-8 byte sequences that are prohibited by the SASLprep algorithm, the raw password will be used without SASLprep processing, instead of throwing an error. This allows the password to be normalized when it is in UTF-8, but still allows a non-UTF-8 password to be used, and doesn’t require the system to know which encoding the password is in.
在带有 SSL 支持的 PostgreSQL 构建中支持 Channel binding。具有通道绑定的 SCRAM 的 SASL 机制名称为 SCRAM-SHA-256-PLUS。PostgreSQL 使用的通道绑定类型为 tls-server-end-point。
Channel binding is supported in PostgreSQL builds with SSL support. The SASL mechanism name for SCRAM with channel binding is SCRAM-SHA-256-PLUS. The channel binding type used by PostgreSQL is tls-server-end-point.
在没有通道绑定的 SCRAM 中,服务器选择一个随机数字,将其传输给客户端,以便与传输的密码哈希中的用户提供的密码进行混合。虽然这可以防止密码哈希在后续会话中成功重新传输,但这并不能防止真实服务器和客户端之间的假服务器传递服务器的随机值并成功进行身份验证。
In SCRAM without channel binding, the server chooses a random number that is transmitted to the client to be mixed with the user-supplied password in the transmitted password hash. While this prevents the password hash from being successfully retransmitted in a later session, it does not prevent a fake server between the real server and client from passing through the server’s random value and successfully authenticating.
使用通道绑定的 SCRAM 通过将服务器证书的签名与传输的密码哈希混合来防止此类中间人攻击。虽然假服务器可以重新传输真实服务器的证书,但它无法访问与该证书匹配的私钥,因此无法证明自己是所有者,从而导致 SSL 连接失败。
SCRAM with channel binding prevents such man-in-the-middle attacks by mixing the signature of the server’s certificate into the transmitted password hash. While a fake server can retransmit the real server’s certificate, it doesn’t have access to the private key matching that certificate, and therefore cannot prove it is the owner, causing SSL connection failure.
Example