【问题标题】:Generating unique tokens in a NodeJS, Crypto Token authentication environment在 NodeJS、加密令牌认证环境中生成唯一令牌
【发布时间】:2018-09-24 16:17:44
【问题描述】:

使用 nodejs 和 crypto,现在,当用户登录时,我会生成一个随机的身份验证令牌:

var token = crypto.randomBytes(16).toString('hex');

我知道这不太可能,但是两个令牌具有相同价值的可能性很小。

这意味着理论上用户可以在另一个帐户上进行身份验证。

现在,我看到了两种明显的方法来通过这个:

  • 当我生成令牌时,查询用户的数据库,看看是否有 已存在具有相同值的令牌。如果是这样,只需生成另一个。如您所见,这并不完美,因为我正在向数据库添加查询。
  • 由于每个用户在我的数据库中都有一个唯一的用户名,我可以
    使用用户名作为密钥生成器生成随机令牌。 这样,就不可能有两个令牌具有相同的值。加密能做到吗?安全吗?

你会怎么做?

【问题讨论】:

    标签: node.js cryptojs


    【解决方案1】:

    不太可能担心它是偶然发生的。我不会牺牲性能来锁定和检查数据库。

    考虑Pro Git 的这段摘录,关于 20 字节 SHA-1 和之间随机冲突的可能性:

    下面是一个示例,让您了解如何获得 SHA-1 碰撞 [偶然]。如果地球上所有 65 亿人都在编程, 每一秒,每个人都在生成等价的代码 整个 Linux 内核历史(100 万个 Git 对象)和推送 将它放到一个巨大的 Git 存储库中,这需要 5 年的时间 存储库包含足够多的对象以有 50% 的概率 单个 SHA-1 对象碰撞。 [对于普通项目]存在更高的概率,即每个 您的编程团队成员将被狼袭击并杀死 在同一晚发生无关事件。

    (SHA-1 冲突can be directly constructed now,因此该引用现在不太适用于 SHA-1,但在考虑随机值的冲突时仍然有效。)

    如果您仍然担心这种可能性,那么您可以轻松地使用更多随机字节而不是 16。

    但是关于您的第二个想法:如果您使用用户名对随机 ID 进行散列,那么该散列可能会发生冲突,就像随机 ID 一样。你什么都没解决。

    【讨论】:

    • 你刚刚给了我另一个想法......当用户登录时,我将搜索哪个用户拥有该特定令牌..如果查询找到多个结果,只需让用户登录再一次 - 这样我可以处理最坏的情况 - 你怎么看?
    • 您的服务器在两个用户之间随机生成令牌冲突的可能性远小于有动机的恶意用户猜测另一个用户的令牌的可能性。如果您认为第一种情况是一个潜在的问题,那么您应该相信第二种情况更多的是一个问题,并通过使用更多随机字节来解决它。如果您认为 16 字节可能足以阻止有动机的暴力攻击者猜测目标用户的令牌,那么应该遵循 16 字节可能足以阻止您的服务器产生冲突。
    • 对加密的一般性很棒的答案
    • 你为什么不把它散列到它被创建的时候,那样它就会是唯一的
    • @TheAnimatrix,当时的哈希值并不比任何其他方法都独特。充其量是毫无意义的建议。
    【解决方案2】:

    您应该始终将UNIQUE 约束添加到您的数据库列。这将创建一个隐式索引来改进对该列的搜索,并确保两条记录中没有一条具有相同的值。因此,在最坏的情况下,您将获得数据库异常而不是安全违规。

    此外,根据需要创建唯一令牌的频率,我认为在大多数情况下,在生成过程中使用数据库查找是完全可以的。如果您的列再次被正确索引,那将是一个非常快的查询。大多数数据库都具有很好的水平可扩展性,因此如果您正在构建下一个 Facebook,它又是一种选择。此外,您可能还需要进行查询以检查电子邮件的唯一性。

    最后,如果您真的关心性能,您总是可以预先生成一百万个唯一令牌并将它们存储在单独的数据库表中以供快速使用。只需设置一个例程来定期检查它的使用情况并根据需要向其中插入更多记录。但是,正如 @MacroMan 在 cmets 中所述,如果有人可以访问预先生成的令牌列表,这可能会产生安全隐患,因此应该避免这种做法。

    【讨论】:

    • "最坏的情况下你会得到一个数据库异常"。不,最坏的情况是,您将泄露记录已经存在的信息并允许会话劫持。预先生成令牌也是非常糟糕的建议。如果数据库被黑客入侵而您不知道怎么办?请不要听从这个建议。
    • @MacroMan 感谢您就预先生成的令牌列表曝光提出的观点。这完全有道理,所以我同意如果在安全敏感的环境(例如身份验证)中使用令牌,应该避免这种做法。但是,您能否解释一下您提到的关于会话劫持的第一个案例?生成代码绝对应该注意此类异常并在失败时重新生成令牌(我就是这样做的)。但是,即使异常会浮出水面并且客户端会看到错误,她怎么能用它来劫持会话呢?
    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 2013-09-20
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 2014-04-16
    相关资源
    最近更新 更多