SCRAM-SHA-256认证失败的根本原因是驱动不支持TLS握手和SHA-256哈希参与完整交换流程,而非单纯版本过低;它强制要求客户端提供明文密码由服务端加盐迭代哈希,旧驱动预哈希或缺失机制实现均导致AUTH START阶段响应非法。

SCRAM-SHA-256 要求驱动支持 TLS 和 SHA-256 摘要
根本原因不是“驱动太老”,而是 SCRAM-SHA-256 在协议层强制要求客户端具备两个能力:一是能完成 TLS 握手(哪怕 MongoDB 部署本身没开 TLS,驱动也得支持协商),二是能执行 SHA-256 哈希并参与完整 SCRAM 交换流程。老版本驱动(比如 Python 的 pymongo < 3.12、Node.js 的 mongodb < 4.0)要么把 SHA-256 当作可选扩展,要么压根没实现服务器端密码哈希校验逻辑。
连接时直接报 AuthenticationFailed 或空凭证错误
典型现象是连接成功建立(没报 MongoServerSelectionError),但一调用 client.connect() 就抛出 AuthenticationFailed,或者日志里出现 "SASL mechanism not supported"。这不是用户名密码错了,而是驱动在 AUTH START 阶段就无法生成合法的 SCRAM-SHA-256 质询响应 —— 它可能连 gs2-header 字段都拼不对,或者盐值解码失败。
- Python 用户注意:
pymongo 3.11支持SCRAM-SHA-256,但必须显式指定authMechanism=SCRAM-SHA-256,否则默认降级到SCRAM-SHA-1 - Node.js 用户注意:
mongodb@3.x默认不启用SCRAM-SHA-256,即使 URI 里写了authMechanism=SCRAM-SHA-256,也要确保minPoolSize和maxPoolSize不为 0,否则连接池初始化阶段就跳过机制协商 - Java 用户注意:
mongo-java-driver 4.3+才完整支持,3.12虽有基础支持但对 FIPS 模式下SCRAM-SHA-256的密钥派生有兼容问题
SCRAM-SHA-256 不允许客户端自行哈希密码
这是最容易被忽略的兼容性断点。MongoDB 服务端在 SCRAM-SHA-256 模式下**只接受明文密码**,由自己完成加盐 + 迭代哈希;而老驱动(尤其某些 C# 或 Go 的早期封装)会试图在客户端预先算好哈希再传过去,结果服务端收不到原始密码,校验必然失败。验证方式很简单:抓包看 authenticate 命令的 pwd 字段是不是明文字符串(Base64 解码后应为可读密码),而不是一串哈希值。
Atlas 或 6.0+ 集群默认禁用 SCRAM-SHA-1 后更明显
当 MongoDB 部署升级到 6.0+ 或 Atlas 启用 FIPS 模式时,SCRAM-SHA-1 会被服务端直接拒绝,此时所有依赖它的旧驱动瞬间失效。这不是驱动 bug,而是协议淘汰 —— SCRAM-SHA-256 的迭代计数(scramSHA256IterationCount)默认为 64000,远高于 SCRAM-SHA-1 的 10000,老驱动即使强行绕过机制检查,也无法在规定轮次内完成计算,超时断连。


















