brenno-duarte / php-secure-password
SecurePassword 是一个用于使用现代加密创建强密码的 PHP 组件。
Requires
- php: ^8.2
- paragonie/sodium_compat: ^1.20
Requires (Dev)
- phpunit/phpunit: ^11
Suggests
- ext-libsodium: To use Sodium encryption
README
SecurePassword 是一个用于使用现代加密创建强密码的 PHP 组件。
为什么使用此组件?
与仅使用 password_hash
或 password_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::DEFAULT
、HashAlgorithm::BCRYPT
、HashAlgorithm::ARGON2I
、HashAlgorithm::ARGON2ID
。
更改加密算法
注意:如果您正在使用构造函数中传递的设置,则可以忽略以下代码。
您可以根据需要更改用于生成哈希的算法类型。您可以使用 PASSWORD_BCRYPT
、PASSWORD_ARGON2I
、PASSWORD_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);
添加选项
注意:如果您正在使用构造函数中传递的设置,则可以忽略以下代码。
在 useDefault
、useBcrypt
和 useArgon2
方法中添加选项。
- useDefault:默认选项,使用数组。
- useBcrypt:您可以根据需要更改
$cost
。默认值为12
。 - useArgon2:您可以根据需要更改
$memory_cost
、$time_cost
和$threads
。默认值为常量PASSWORD_ARGON2_DEFAULT_MEMORY_COST
、PASSWORD_ARGON2_DEFAULT_TIME_COST
和PASSWORD_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