mongodb - 使用 MongoDB 生成的 _ids 作为 "secret data"(例如,OAuth token )

标签 mongodb

MongoDB _id 字段是否足够随机/不可猜测以充当 secret 数据?

例如:如果我正在构建服务器端 OAuth,我可以使用 _id 作为用户的 OAuth token 吗?我想这样做是因为它为数据库提供了清洁度和可索引性(例如,“tokens._id”=> oauth_token)。

检查 MongoDB _id 对象的结构,它们似乎是相当随机的,但我确实对恶意实体暴力猜测一个存在一些挥之不去的担忧。

最佳答案

简而言之,没有。 Mongo ObjectIds 很容易猜到。特别是在高负载下,这些通常是连续的数字,因为时间戳、机器和进程 ID 不会改变。如果你看 the structure of Objectid ,它们是由

a 4-byte timestamp, 
a 3-byte machine identifier, 
a 2-byte process id, and 
a 3-byte counter, starting with a random value.

因此,它们几乎没有随机性。我经常在数据库中看到连续的 id,例如,如果某些 Controller 操作写入域对象,以及快速连续的日志条目。

如果时间戳可以猜到并且机器ID是可确定的(除非你有一个巨大的集群),那么就只剩下五个字节了。通过查看许多生成的 id,我可能可以将其减少到 50 个进程,因此有效熵在 28 位范围内。这仍然很难猜测,但对于访问 token 来说风险太大。

改用加密性强的伪随机数生成器并从中创建 token 。例如,在 .NET 中,RNGCryptoServiceProvider 允许创建任意长度的随机数据。

作为旁注,我建议在您的 OAuthTokens 周围添加一个额外的加密包装器,原因有两个:

a) 您希望能够快速确定无效 token 。一个有效的加密 shell 可能仍然包含一个无效的 token (一个被撤销或过期的授权),但你不必每次都对数据库进行暴力攻击。另外,客户端

b) 客户端可以反复请求 token 。虽然这不是必需的,但我所知道的几乎所有系统每次都会返回不同的 token (无论它们是否 self 验证)。通常,这是因为 token 本身的有效期有限。这与 OAuth 授权的有效期不同。

在数据库中,您真正要存储的是授权,即某个用户授予某个客户端的权限。如果删除此授权,则所有 token 都将无效。每次都插入一个新 token 非常不方便,因为用户必须删除所有 token 才能有效地删除应用程序授权。

关于mongodb - 使用 MongoDB 生成的 _ids 作为 "secret data"(例如,OAuth token ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15435530/

相关文章:

javascript - 使用nodejs异步回调处理循环

javascript - 在 javascript 中创建一个 ISO 日期对象

java - 自动配置数据源失败 : 'spring.datasource.url' is not specified

ruby-on-rails - 在 mongo ruby​​ 驱动程序中使用 DBRef:(#<Mongo::DBRef:0x0056466ed55e48> 的未定义方法 `bson_type')

javascript - MongoDB——javascript查询语言

javascript - 来自 aggregate() 和 find() 的 promise 以及用于 NodeJS 的 MongoDB 驱动程序

javascript - MongoDB Schema 优化以保存用户联系人

mongodb - 如何选择字段总和大于MongoDB中的值的位置

mongodb - ElasticSearch 与其他存储结合的典型用法是什么?

mongodb - 不使用 map/reduce 在 mongodb 中联合查询