跳到内容

如何强化密码

Shield 允许您自定义密码相关设置,以提高密码安全性。

最小密码长度

说到密码,最重要的因素是密码中的字符数。您可以使用 密码强度测试工具 来检查密码强度。短密码可能在不到一天的时间内被破解。

在 Shield 中,您可以设置用户的最小密码长度。该设置是 app/Config/Auth.php 中的 $minimumPasswordLength。默认值为 8 个字符。这是 NIST 推荐的最小值。但是,一些组织建议使用 12 到 14 个字符。

密码越长,就越安全。考虑增加值。

注意

当您使用 strong_password[] 验证规则验证密码时,此检查有效。如果您在 $passwordValidators 中禁用了 CompositionValidator(默认启用),此检查将无效。

密码哈希算法

您可以通过 app/Config/Auth.php 中的 $hashAlgorithm 更改密码哈希算法。默认值为 PASSWORD_DEFAULT,在撰写本文时为 PASSWORD_BCRYPT

PASSWORD_BCRYPT 表示使用 bcrypt 算法创建新的密码哈希。

如果您的 PHP 已编译并支持 Argon2,则可以使用 PASSWORD_ARGON2ID

PASSWORD_BCRYPT

PASSWORD_BCRYPT 有一个配置 $hashCost。成本越大,哈希密码就越强。

您可以使用以下代码找到合适的成本

<?php
/**
 * This code will benchmark your server to determine how high of a cost you can
 * afford. You want to set the highest cost that you can without slowing down
 * you server too much. 8-10 is a good baseline, and more is good if your servers
 * are fast enough. The code below aims for ≤ 50 milliseconds stretching time,
 * which is a good baseline for systems handling interactive logins.
 *
 * From: https://php.ac.cn/manual/en/function.password-hash.php#refsect1-function.password-hash-examples
 */
$timeTarget = 0.05; // 50 milliseconds

$cost = 8;
do {
    $cost++;
    $start = microtime(true);
    password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
    $end = microtime(true);
} while (($end - $start) < $timeTarget);

echo "Appropriate Cost Found: " . $cost;

限制

使用 PASSWORD_BCRYPT 时有两个限制

  1. 密码将被截断为最大长度 72 字节。
  2. 密码将在第一个 NULL 字节 (\0) 处截断。
72 字节问题

如果用户提交的密码长度超过 72 字节,则会发生验证错误。如果此行为不可接受,请考虑

  1. 将哈希算法更改为 PASSWORD_ARGON2ID。它没有这样的限制。
NULL 字节问题

这是因为 PASSWORD_BCRYPT 不是二进制安全的。普通用户无法在密码字符串中发送 NULL 字节,因此在大多数情况下这不是问题。

但如果此行为不可接受,请考虑

  1. 添加验证规则以禁止 NULL 字节或控制代码。
  2. 或将哈希算法更改为 PASSWORD_ARGON2ID。它是二进制安全的。

PASSWORD_ARGON2ID

PASSWORD_ARGON2ID 有三个配置 $hashMemoryCost$hashTimeCost$hashThreads

如果您使用 PASSWORD_ARGON2ID,则应使用 PHP 的常量

public int $hashMemoryCost = PASSWORD_ARGON2_DEFAULT_MEMORY_COST;

public int $hashTimeCost = PASSWORD_ARGON2_DEFAULT_TIME_COST;
public int $hashThreads  = PASSWORD_ARGON2_DEFAULT_THREADS;

最大密码长度

默认情况下,Shield 具有最大密码长度的验证规则。

  • PASSWORD_BCRYPT 为 72 字节
  • 其他为 255 个字符

您可以自定义验证规则。请参阅 自定义验证规则

$supportOldDangerousPassword

app/Config/Auth.php 中有 $supportOldDangerousPassword,这是用于使用 Shield 旧版本中存储的密码的设置,这些密码是 易受攻击 的。

此设置已弃用。如果您已将此设置设置为 true,则应尽快将其更改为 false,并在数据库中删除旧的哈希密码。

注意

此设置将在 v1.0.0 正式版中删除。