确保密码存储方案安全的最简单方法是使用标准库。
因为安全性往往比大多数程序员单独解决的问题要复杂得多,并且存在更多不可见的搞砸可能性,所以使用标准库几乎总是最简单和最安全的(如果不是唯一的)可用选项。
新的 PHP 密码 API (5.5.0+)
如果您使用的是 PHP 5.5.0 或更新版本,您可以使用新的简化密码哈希 API
使用 PHP 的密码 API 的代码示例:
<?php
// $hash is what you would store in your database
$hash = password_hash($_POST['password'], PASSWORD_DEFAULT, ['cost' => 12]);
// $hash would be the $hash (above) stored in your database for this user
$checked = password_verify($_POST['password'], $hash);
if ($checked) {
echo 'password correct';
} else {
echo 'wrong credentials';
}
(如果您仍在使用旧版 5.3.7 或更新版本,您可以安装ircmaxell/password_compat以访问内置函数)
改进盐渍哈希:加胡椒
如果您想要额外的安全性,安全人员现在(2017 年)建议在(自动)加盐密码哈希中添加“胡椒”。
有一个简单的类可以安全地实现这种模式,我推荐:
Netsilik/PepperedPasswords
( github )。
它带有 MIT 许可证,因此您可以随心所欲地使用它,即使在专有项目中也是如此。
使用代码示例Netsilik/PepperedPasswords
:
<?php
use Netsilik/Lib/PepperedPasswords;
// Some long, random, binary string, encoded as hexadecimal; stored in your configuration (NOT in your Database, as that would defeat the entire purpose of the pepper).
$config['pepper'] = hex2bin('012345679ABCDEF012345679ABCDEF012345679ABCDEF012345679ABCDEF');
$hasher = new PepperedPasswords($config['pepper']);
// $hash is what you would store in your database
$hash = $hasher->hash($_POST['password']);
// $hash would be the $hash (above) stored in your database for this user
$checked = $hasher->verify($_POST['password'], $hash);
if ($checked) {
echo 'password correct';
} else {
echo 'wrong credentials';
}
旧标准库
请注意:你应该不再需要这个了!这只是出于历史目的。
看看:便携式 PHP 密码散列框架:phpass并确保CRYPT_BLOWFISH
尽可能使用该算法。
使用 phpass (v0.2) 的代码示例:
<?php
require('PasswordHash.php');
$pwdHasher = new PasswordHash(8, FALSE);
// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );
// $hash would be the $hash (above) stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
echo 'password correct';
} else {
echo 'wrong credentials';
}
PHPass 已经在一些非常知名的项目中实现:
- phpBB3
- WordPress 2.5+ 以及 bbPress
- Drupal 7 版本,(可用于 Drupal 5 和 6 的模块)
- 其他
好处是您不必担心细节,这些细节已经由有经验的人编写,并由互联网上的许多人审查。
有关密码存储方案的更多信息,请阅读Jeff的博客文章:您可能错误地存储了密码
无论你做什么,如果你采取“我会自己做,谢谢你”的方法,不要使用MD5
orSHA1
。它们是很好的散列算法,但出于安全目的被认为是损坏的。
目前,使用crypt和 CRYPT_BLOWFISH 是最佳实践。
PHP 中的 CRYPT_BLOWFISH 是 Bcrypt 哈希的实现。Bcrypt 基于 Blowfish 分组密码,利用其昂贵的密钥设置来减慢算法速度。