【问题标题】:I want to use bcrypt.compare together with mongoose/mongo enginee search我想将 bcrypt.compare 与 mongoose/mongo enginee 搜索一起使用
【发布时间】:2020-07-31 19:55:54
【问题描述】:

考虑这段代码:

const hashPassword = function(plainText) {
  return crypto
    .createHmac(process.env.Secret_hash_Password, "secret key")
    .update(plainText)
    .digest("hex");
};

您可能已经注意到,这是一个使用crypto 的简单散列函数。

现在考虑这段代码摘录:

bcrypt.compare(password, user.password, (err, isMatch) => {....}

您可能已经注意到,这是一个使用bcryptjs 的简单比较散列函数。

我相信每个人都会同意,第二个是最安全的

现在考虑问题:

我有一个密钥要存储在 mongo 上,这个密钥是敏感信息,所以我决定对它进行哈希处理,这样就没有人可以解密它了。 这个密钥用于制作mongo 搜索,这是只有用户拥有的信息,一种密码。

解决方案:使用第一个代码,虽然不能解密,但如果输入相同,则可以得到相同的哈希结果。

问题:我的解决方案是使用一种众所周知的容易被黑客入侵的技术,以某种方式可以访问服务器的人只需要输入几个输入,一旦他们得到相同的输出,他们明白了!这是我的解决方案的一个众所周知的缺陷。

所需的解决方案:将第二个代码与 mongo 一起使用。

讨论:我可以简单地使用find({}) 获取所有数据库信息,然后申请ForEachbcrypt.compare,尽管如此,我从研究中知道mongo 针对搜索进行了优化,例如他们使用索引。如果能够将bcrypt.compare 作为自定义函数传递给 mongo 搜索引擎,那就太好了。

有人建议“增加 bcrypt 盐循环。”:我不能使用盐,因为这会改变密钥,每当我需要比较时,它就会改变。 bcrypt.compareexists 可以克服这个问题,但是 mongo/mongoose 查询没有这样的内部引擎。

我脑子里的东西,用伪代码写的:

Model.findOne({bcrypt.compare (internalID, internalID')}) //return when true

其中:bcrypt.compare(internalID, internalID') 将是一种回调函数,在每次搜索时,mongo 将使用此函数与 internalID',当前的 internalID 进行比较,并返回产生的文档真的。

有什么建议、意见或任何事情吗?

PS。我正在使用猫鼬。

【问题讨论】:

  • > 您关心的问题:问题:我的解决方案是使用一种众所周知的容易被黑客入侵的技术,有人只需要输入几个输入,一旦他们得到相同的输出,他们就明白了!这是我的解决方案中的一个众所周知的缺陷。 > 潜在解决方案:增加 bcrypt 盐轮。
  • 这就是问题所在:我不能使用盐,因为在这种情况下,我将没有相同的密钥。每当我使用find() 或任何其他函数时,我都需要提供一个与数据库中的密钥相同的密钥:bcrypt.compare 不需要知道密钥,但与 mongo/mongoose 相关的查询需要。想象一下每次我想寻找它改变的id?这是行不通的。感谢您的回复!
  • 你能告诉我们你的架构吗?
  • 嘿,代码很大,包括模式,如果我添加代码就会产生问题。我会看看我是否发布一个简短的版本,但我相信我所说的已经足够了。我的代码有效,我只是想改进。
  • 是您试图与用户数据一起存储在 mongo 中的某种会话密钥(因为它来自客户端)?还是用户访问存储在其他集合中的数据的某种密码?

标签: mongodb encryption mongoose bcrypt cryptojs


【解决方案1】:

据我了解,您永远不希望任何人知道患者 ID(无法从现实生活中的患者 ID 中发现),甚至是数据库管理员(当然还有黑客)。 我觉得你的设计有点乱。 首先 - 索引使用 B 树数据结构进行更快的查找,因此您必须提供准确的字符串进行查找,并且根据您的不可散列 ID 的条件,索引将不起作用。因此,您必须遍历该医生的每个患者 ID 并进行比较以获得真实结果,这是计算量非常大且坦率地说糟糕的设计。 有多种方法可以解决这个问题——取决于你的信任和偏执程度。

我认为使用 cryptojs 是正确的解决方案。现在您必须为密钥/解决方案添加一些随机性。基本上你用 cryptojs 对 id 进行散列,但你可以从医生本身获取密钥,然后用该密钥对每个 id 进行散列,而不是自己提供密钥。现在,每次医生更改密钥(使用某种消息队列)时,您都必须对每个患者 ID 进行 unhash 和哈希处理。 您还可以在保存之前对医生输入的密钥进行哈希处理,并且每次(两次!)医生想要通过患者 ID 查找时都必须取消哈希处理。

根据您希望应用程序服务的用户数量,如果数量足够低 - 我的解决方案会起作用。但是太多的用户,你必须增加计算资源,并且可能投资一些安全措施,而不是我的矫枉过正的解决方案。无论如何,您为什么要向黑客丢失密钥?

祝你好运。

【讨论】:

  • 您好,谢谢您的回答。我相信我目前的解决方案已经足够好了,我只是想看看我的第二个猜测是否可行,似乎不行。我目前的系统是一个原型,我有一个有点偏执的“老板”,因此,我想确保他没有理由抱怨我的设计。我相信我现在有一个很好的解决方案。我担心的是,如果有人,甚至是管理员,可以访问它。有严格的法律,并且有理由保护患者,而信任一旦被打破,就很难恢复。因此,我们的用户应该信任系统!
  • ",您可以从医生本身获取密钥,然后用该密钥对每个 id 进行哈希处理.." 我喜欢这样 :)
猜你喜欢
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-15
  • 2015-12-03
  • 2020-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多