0

我正在创建一个 PHP 登录系统。用户将收到一封电子邮件,其中包含指向将检查一次性链接的网站的一次性链接,并以 cookie/会话的形式提供令牌。我的问题是如何拆分令牌和/或一次性链接以防止定时攻击。

我的会话表:

- uid (AI PK)
- datecreated (when welcome email sent with one-time link)
- datevalidated (once one-time link is confirmed and token loaded to the user as cookie/session)
- email (email to which the welcome email has to be sent)
- onetimelink (https://example.com/login/$onetimelink - sent via email)
- token (token which authenticates users for up to a week)

令牌将使用以下代码生成并保存到数据库:

$onetimelink = bin2hex(random_bytes(15));
$token = bin2hex(random_bytes(15));
4

1 回答 1

2

这就是我将如何做到这一点。

生成电子邮件时

  1. 使用类似这样的技术创建一个难以猜测的随机文本字符串标记。PHP 随机字符串生成器。5 位/字符的 20 个字符在令牌中为您提供 100 位随机性。那应该绰绰有余了。

  2. 使用 php password_hash()像处理密码一样处理该令牌。

  3. 将 password_hash() 的输出存储在 SQL 表中。不要将实际令牌存储在您的表中。

  4. 将令牌放入电子邮件的 URL 中。(&token=zSBXsEkhNX6S8h5fjFbB例如)

当用户显示电子邮件中的 URL 时验证令牌时

  1. 从您的 SQL 表中读取散列标记。

  2. 使用password_verify()(旨在防止计时和其他网络蠕变攻击)来验证 URL 上的令牌。如果 password_verify() 失败,使用非常通用的消息拒绝请求,例如“抱歉,链接无效”,而不是“您的令牌错误”。

  3. 验证令牌后,更新或删除表中的行,以便不再存在散列令牌。

维护您的餐桌时

删除或更新包含陈旧(太旧)散列标记的行。不要让陈旧令牌的哈希值在您的系统中四处飘荡。

如果您以这种方式做事,您将使用久经考验的加密模块。这比创建自己的更安全。除非您是 Bruce Schneier 或 Whit Diffie,否则最好将这项工作留给专家。

这种令牌称为

于 2020-11-23T14:34:13.390 回答