MongoDB用户密码存储及SCRAM-SHA-1认证原理与字段含义问询
嘿,我来帮你把这些MongoDB认证的细节掰明白:
1. MongoDB如何存储用户密码?
MongoDB默认采用**SCRAM(Salted Challenge Response Authentication Mechanism)**机制来存储用户密码,完全不会存储明文密码。它会对用户密码执行以下操作后存储:
- 生成一个随机的salt(盐值)
- 用指定的哈希算法(比如你文档里的SHA-1)和迭代次数,对密码加盐后进行多次哈希运算
- 最终将盐值、迭代次数,以及运算生成的两个关键密钥(storedKey、serverKey)一起存在用户文档的
credentials字段下,对应你看到的结构。
2. 给定用户文档的认证流程与字段解析
先看这个用户文档的结构:
{ "_id": "admin.123", "user": "123", "db": "admin", "credentials": { "SCRAM-SHA-1": { "iterationCount": 10000, "salt": "f9SdPCCcBOwk71/xDkj6Sw==", "storedKey": "83mNhTYctOdlYsL1sbnfpiA0uxw=", "serverKey": "09H9aEKKufaoCDxqUkHntx6EqrE=" } }, "roles": [] }
认证流程是怎样的?
当用户发起认证请求时,MongoDB和客户端会完成SCRAM的双向验证流程:
- 客户端先发送用户名和目标认证数据库(这里是
admin) - 服务端返回文档里的
salt和iterationCount给客户端 - 客户端用自己输入的密码、拿到的salt和迭代次数,计算出
clientKey和客户端证明(client proof),然后把clientKey的哈希值(也就是和storedKey对应的内容)和client proof发给服务端 - 服务端对比客户端发来的哈希值和自己存储的
storedKey,如果匹配,说明客户端拥有正确的密码;接着服务端用存储的serverKey生成服务端证明(server proof)返回给客户端 - 客户端验证server proof,确认服务端确实持有正确的密钥材料,双向认证完成。
storedKey和serverKey分别代表什么?
- storedKey:它是客户端密码推导出来的
ClientKey的哈希值(对应所用的算法,这里是SHA-1)。服务端用它来验证客户端是否真的知道正确密码——因为只有用正确密码,客户端才能计算出和storedKey一致的哈希值。 - serverKey:这是用相同密码、salt和迭代次数推导出来的另一个HMAC密钥。服务端用它生成server proof,让客户端可以验证服务端的合法性,避免中间人攻击。
此类信息是否公开?
绝对不能公开!这些字段是MongoDB认证体系的核心保密材料,虽然它们不是明文密码,但一旦泄露,攻击者可以模拟服务端响应,或者通过彩虹表等方式逆向破解原密码,严重破坏安全性。
关于这些字段的官方说明,MongoDB的文档里其实是基于RFC 5802(SCRAM的标准规范)来实现的,你可以去查阅MongoDB官方的认证机制细节文档,里面会明确提到这些字段的作用~
内容的提问来源于stack exchange,提问作者Krasimir




