brenno-duarte/php-secure-password

SecurePassword 是一个用于使用现代加密创建强密码的 PHP 组件。

3.1.4 2024-09-12 12:59 UTC

This package is auto-updated.

Last update: 2024-09-12 13:00:35 UTC


README

SecurePassword 是一个用于使用现代加密创建强密码的 PHP 组件。

为什么使用此组件?

与仅使用 password_hashpassword_verify 不同,SecurePassword 会添加一个秘密条目(通常称为 pepper),使生成的哈希难以破解。

要求

PHP >= 8.2

通过 Composer 安装

composer require brenno-duarte/php-secure-password

如何使用

下面的代码演示了创建哈希的示例。 createHash 方法生成密码哈希和 "peeper",而 getHash 方法返回生成的哈希。

use SecurePassword\SecurePassword;

$password = new SecurePassword();
$hash = $password->createHash('my_password')->getHash();

/** Return string */
var_dump($hash);

设置

您可以通过在构造函数中输入以下代码来更改加密设置,而无需使用以下列出的方法。

use SecurePassword\AlgorithmEnum;

$config = [
    'algo' => AlgorithmEnum::DEFAULT,
    'cost' => 12,
    'memory_cost' => PASSWORD_ARGON2_DEFAULT_MEMORY_COST,
    'time_cost' => PASSWORD_ARGON2_DEFAULT_TIME_COST,
    'threads' => PASSWORD_ARGON2_DEFAULT_THREADS
];

$password = new SecurePassword($config);

您可以使用以下加密:HashAlgorithm::DEFAULTHashAlgorithm::BCRYPTHashAlgorithm::ARGON2IHashAlgorithm::ARGON2ID

更改加密算法

注意:如果您正在使用构造函数中传递的设置,则可以忽略以下代码。

您可以根据需要更改用于生成哈希的算法类型。您可以使用 PASSWORD_BCRYPTPASSWORD_ARGON2IPASSWORD_ARGON2ID 以及甚至 PASSWORD_DEFAULT

  • useDefault() 将使用标准加密
  • useBcrypt() 将使用 Bcrypt 加密
  • useArgon2() 将使用 Argon2 加密
  • useArgon2(true) 通过传递 true 将使用 Argon2d 加密
# standard encryption
$hash = $password->useDefault()->createHash('my_password')->getHash();

# Bcrypt encryption
$hash = $password->useBcrypt()->createHash('my_password')->getHash();

# Argon2 encryption
$hash = $password->useArgon2()->createHash('my_password')->getHash();

# Argon2d encryption (with `true`)
$hash = $password->useArgon2(true)->createHash('my_password')->getHash();

如果没有提供算法类型,则默认加密为 'PASSWORD_DEFAULT'。

返回有关给定哈希的信息

要返回创建的哈希的信息,请使用 getHashInfo 方法。

$hash = $password->createHash('my_password')->getHashInfo();

/** Return array */
var_dump($hash);

验证密码是否与哈希匹配

要验证使用 createHash 生成的哈希是否有效,您可以使用两种方式使用 verifyHash

# First way
$hash = $password->createHash('my_password')->getHash();
$res = $password->verifyHash('my_password', $hash);

# Second way
$hash = $password->createHash('my_password')->verifyHash();

/** Return bool */
var_dump($res);

为了使时间攻击更难,verifyHash 方法将等待 0.25 秒(250000 微秒)然后返回值。您可以更改此时间,通过更改第三个参数。

# First way
$hash = $password->createHash('my_password')->getHash();
$res = $password->verifyHash('my_password', $hash, 300000);

# Second way
$hash = $password->createHash('my_password')->verifyHash(wait_microseconds: 300000);

/** Return bool */
var_dump($res);

注意:如果您正在使用构造函数中传递的设置,则可以忽略以下代码。

您可以更改用于检查哈希的算法类型。

$hash = $password->useArgon2()->createHash('my_password')->getHash();
$res = $password->useArgon2()->verifyHash('my_password', $hash);

/** Return bool */
var_dump($res);

需要重新哈希

如果已更改加密类型,则可以使用新的加密生成新的哈希。 needsHash() 方法检查报告的哈希是否需要重新生成。否则,它将返回 false

示例 1

$password = new SecurePassword();
$hash = $password->useArgon2()->createHash('my_password')->getHash();
$needs = $password->useDefault()->needsRehash('my_password', $hash);

/** Return string */
var_dump($needs);

示例 2

$hash = $password->createHash('my_password')->getHash();

$password = new SecurePassword([
    'algo' => AlgorithmEnum::BCRYPT
]);
$needs = $password->needsRehash('my_password', $hash);

/** Return false */
var_dump($needs);

添加选项

注意:如果您正在使用构造函数中传递的设置,则可以忽略以下代码。

useDefaultuseBcryptuseArgon2 方法中添加选项。

  • useDefault:默认选项,使用数组。
  • useBcrypt:您可以根据需要更改 $cost。默认值为 12
  • useArgon2:您可以根据需要更改 $memory_cost$time_cost$threads。默认值为常量 PASSWORD_ARGON2_DEFAULT_MEMORY_COSTPASSWORD_ARGON2_DEFAULT_TIME_COSTPASSWORD_ARGON2_DEFAULT_THREADS
# standard encryption
$hash = $password->useDefault([])->createHash('my_password');

# Bcrypt encryption
$hash = $password->useBcrypt(12)->createHash('my_password');

# Argon2 encryption
$hash = $password->useArgon2(false, PASSWORD_ARGON2_DEFAULT_MEMORY_COST, PASSWORD_ARGON2_DEFAULT_TIME_COST, PASSWORD_ARGON2_DEFAULT_THREADS)->createHash('my_password');

# Argon2d encryption (with `true`)
$hash = $password->useArgon2(true, PASSWORD_ARGON2_DEFAULT_MEMORY_COST, PASSWORD_ARGON2_DEFAULT_TIME_COST, PASSWORD_ARGON2_DEFAULT_THREADS)->createHash('my_password');

使用 OpenSSL 和 Sodium 加密

Secure Password 组件 paragonie/sodium_compat。因此,不需要使用 PECL 格式的 Sodium 库。

您可以使用 Encryption 类使用 OpenSSL 和 Sodium 加密

use SecurePassword\Encrypt\Encryption;

$encryption = new Encryption('your-key');

//Encrypt the message
$encrypt = $encryption->encrypt("This is a text");
echo $encrypt;

您可以通过调用解密方法来解密令牌

$encryption = new Encryption('your-key');

//Decrypt the message
$decrypt = $encryption->decrypt($encrypt);
echo $decrypt;

您可以将支持的适配器传递给类,例如

使用 OpenSSL

$encryption = new Encryption(new OpenSslEncryption('your-key'));

使用 Sodium

$encryption = new Encryption(new SodiumEncryption('your-key'));

默认情况下将使用 OpenSSL,您可以使用任何您想要的。

更改秘密条目(建议)

建议更改将添加到您密码中的秘密入口(或pepper)。使用setPepper来更改。

$password = new SecurePassword();
$password->setPepper('new_pepper');

默认情况下,setPepper方法使用OpenSSL加密。但是,如果您想使用Sodium加密,也可以。

// Use OpenSSL
$password->setPepper('new_pepper', 'openssl');

// Use Sodium
$password->setPepper('new_pepper', 'sodium');

获取理想的加密成本

这里有一个简单的函数,可以帮助您确定应该为您的服务器使用什么成本参数,以确保您在这个范围内。

$optimal_cost = SecurePassword::getOptimalBcryptCost('my_password');

$password = new SecurePassword([
    'cost' => $optimal_cost
]);
$hash = $password->createHash('my_password')->getHash();

许可

MIT