使用永久登录Cookie时,如何对照DB中的bcrypt哈希令牌检查Cookie令牌?

Pro*_*irl 5 php mysql cookies login bcrypt

这种流行的持久登录Cookie 解决方案中该解决方案涉及生成随机的128位“令牌”以保存在用户的Cookie中,Jens Roland建议:

并且不要将永久性登录COOKIE(令牌)存储在您的数据库中,仅是一种哈希!登录令牌是等效的密码,因此,如果攻击者将您的手放在您的数据库上,则他/她可以使用这些令牌登录到任何帐户,就像它们是明文登录密码组合一样。因此,在存储持久性登录令牌时,请使用强盐散列(bcrypt / phpass)。

但是,当您对Cookie令牌进行加密时,您将如何对照数据库中的加密令牌来检查Cookie令牌以确认Cookie登录有效?(因为加密始终使用随机盐)?

换句话说,您将无法对Cookie令牌进行bcrypt加密,然后在数据库中寻找匹配项,因为您将永远找不到匹配的令牌,因此,如何按照推荐的解决方案将其与数据库中的哈希版本进行实际匹配(“服务器保留一个由数字->用户名关联组成的表,该表将被查找以验证cookie的有效性。

编辑:

请记住,按照上面链接的推荐解决方案,单个用户可以为不同设备使用多个 Cookie /令牌。我提到这是因为提交了一个答案(此答案已被删除),它假定每个用户只有一个令牌。

Jen*_*and 1

正如前面的答案中提到的,bcrypt 将随机盐存储为哈希的一部分,因此数据库中的每个令牌条目都将包含random_salthashed_token

当验证“记住我”登录 cookie(应由userid和组成token)时,您需要迭代该用户 ID 的每个令牌条目(通常只有一个条目,绝不会超过几个),并使用存储的随机盐:

foreach (entry in stored_tokens_for_user) {
    if (entry.hashed_token == bcrypt(cookie.token, entry.random_salt))
        return true;
}
return false;
Run Code Online (Sandbox Code Playgroud)

(如果您的数据库内置支持 bcrypt 作为查询语法的一部分,您可以创建一个准备好的语句来为您执行此操作)

  • 谢谢你的回答,这就是我的怀疑。然而,这不是完全矫枉过正吗(更不用说不必要的复杂和耗时)?简单地对 128 位 Cookie 令牌进行未加盐的 256 位 SHA 哈希是否足以保证令牌在数据库中的安全,同时提供直接哈希匹配的速度和便利性?我理解为什么您永远不应该对用户密码进行简单的无盐哈希,但是实际破解完全随机的 128 位令牌的单个无盐 256 位 SHA 哈希需要多长时间? (2认同)