【问题标题】:How to generate human-readable access codes?如何生成人类可读的访问代码?
【发布时间】:2017-08-08 15:59:19
【问题描述】:

我正在 PHP/Laravel 中构建一个在线和邮寄投票系统,该系统需要一个访问令牌,该令牌由实际用户或管理员在某个时候输入。因此,我假设必须生成令牌,并且不能通过数据库转储追溯到原始用户。

生成此类代码的最佳方法是什么?我查看过 Hashids,但不确定这是否是一个合适的解决方案,除非可以使用以秒为单位的选票创建时间戳作为第二个值与选票 ID 一起使用。

【问题讨论】:

  • 如果我理解了这个问题,我相信您会希望将password_encrypt()uniqid() 一起使用。您将添加uniqid() 在数据库中生成的password_encrypt()ed 字符串作为访问权限用户/管理员将获得的代码,当用户/管理员键入它时,您将使用password_verify() 来验证它是否与数据库中的字段匹配。
  • @Alesana:这是个好主意,但uniqid() 的问题在于它相当长。我怀疑目标用户在在线标记他们的选票之前会想啄掉 13 个字母和数字,或者当他们可能收到他们必须手动输入的 30 多张选票时,管理员也会这样做。
  • 如果你想要一个更短的 id,你可以这样做,但碰撞的可能性很小(两个 id 相同的可能性),但是碰撞的可能性仍然存在。我建议使用带有 crc32b 算法的哈希函数来生成 8 个字符的代码。例如,hash('crc32b', uniqid());
  • 请注意,当我说使用password_encrypt()时,我实际上是指password_hash()

标签: php laravel token laravel-5.4


【解决方案1】:

使用CSPRNG(例如openssl_random_pseudo_bytes)创建一个随机字节数组,然后Base58 对结果进行编码。这将为唯一性级别提供最短的人类可用字符串。

Base58 是一个非常人性化的字符集,没有容易混淆的字符。这种用法的一个例子是比特币。

这里是字符集:
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz

【讨论】:

    【解决方案2】:

    最好的和最快的之一是:

    $token = bin2hex(openssl_random_pseudo_bytes(int));
    

    二进制安全和加密安全,但如果你想得到想要的长度,你必须剪掉它,然后你会更容易挂钩仅由 16 个字符组成的令牌。如果你想获得人类可靠的字符串,你必须自己实现它,这是很长的路要走。我使用加密安全扩展 SafeToken 做了这样的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      • 2012-01-05
      • 2019-11-28
      相关资源
      最近更新 更多