如何安全地存储我的用户密码?
这比普通的 MD5 安全多少?我刚刚开始研究密码安全性.我对 PHP 很陌生.
How much more safe is this than plain MD5? I've just started looking into password security. I'm pretty new to PHP.
$salt = 'csdnfgksdgojnmfnb';
$password = md5($salt.$_POST['password']);
$result = mysql_query("SELECT id FROM users
WHERE username = '".mysql_real_escape_string($_POST['username'])."'
AND password = '$password'");
if (mysql_num_rows($result) < 1) {
/* Access denied */
echo "The username or password you entered is incorrect.";
}
else {
$_SESSION['id'] = mysql_result($result, 0, 'id');
#header("Location: ./");
echo "Hello $_SESSION[id]!";
}
推荐答案
确保密码存储方案安全的最简单方法是使用标准库.
The easiest way to get your password storage scheme secure is by using a standard library.
由于安全性往往比大多数程序员单独解决的问题要复杂得多,并且存在更多不可见的搞砸可能性,因此使用标准库几乎总是最简单、最安全(如果不是唯一的话)的可用选项.
Because security tends to be a lot more complicated and with more invisible screw up possibilities than most programmers could tackle alone, using a standard library is almost always easiest and most secure (if not the only) available option.
如果您使用的是 PHP 5.5.0 或更新版本,您可以使用新的简化密码哈希 API
If you are using PHP version 5.5.0 or newer, you can use the new simplified password hashing API
使用 PHP 密码 API 的代码示例:
Example of code using PHP's password 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 到可以访问内置函数)
(In case you are still using legacy 5.3.7 or newer you can install ircmaxell/password_compat to have access to the build-in functions)
如果您想要额外的安全性,安全人员现在(2017 年)建议添加 'pepper' 到(自动)加盐密码哈希.
If you want extra security, the security folks now (2017) recommend adding a 'pepper' to the (automatically) salted password hashes.
有一个简单的类可以安全地实现这种模式,我建议:Netsilik/PepperedPasswords(github).
它带有 MIT 许可证,因此您可以随意使用它,即使在专有项目中也是如此.
There is a simple, drop in class that securely implements this pattern, I recommend:
Netsilik/PepperedPasswords
(github).
It comes with a MIT License, so you can use it however you want, even in proprietary projects.
使用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';
}
请注意:您应该不再需要这个了!这只是出于历史目的.
Please note: you should not be needing this anymore! This is only here for historical purposes.
看看:便携式 PHP 密码哈希框架:phpass 并确保尽可能使用 CRYPT_BLOWFISH
算法.
Take a look at: Portable PHP password hashing framework: phpass and make sure you use the CRYPT_BLOWFISH
algorithm if at all possible.
使用 phpass (v0.2) 的代码示例:
Example of code using 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';
}
PHPPass 已在一些非常知名的项目中实现:
PHPass has been implemented in some quite well known projects:
- phpBB3
- WordPress 2.5+ 以及 bbPress
- Drupal 7 版本,(可用于 Drupal 5 和 6 的模块)
- 其他
好处是您不必担心细节,这些细节已由有经验的人编写,并由互联网上的许多人审查.
The good thing is that you do not need to worry about the details, those details have been programmed by people with experience and reviewed by many folks on the internet.
有关密码存储方案的更多信息,请阅读 Jeff 的博文:您可能存储的密码不正确
For more information on password storage schemes, read Jeff`s blog post: You're Probably Storing Passwords Incorrectly
如果你选择我会自己做,谢谢"的方法,无论你做什么,不要使用 MD5
或 SHA1
了.它们是很好的散列算法,但出于安全目的考虑已损坏.
Whatever you do if you go for the 'I'll do it myself, thank you' approach, do not use MD5
or SHA1
anymore. They are nice hashing algorithm, but considered broken for security purposes.
目前,最好使用 crypt 和 CRYPT_BLOWFISH.
PHP 中的 CRYPT_BLOWFISH 是 Bcrypt 哈希的实现.Bcrypt 基于 Blowfish 分组密码,利用其昂贵的密钥设置来降低算法速度.
Currently, using crypt, with CRYPT_BLOWFISH is the best practice.
CRYPT_BLOWFISH in PHP is an implementation of the Bcrypt hash. Bcrypt is based on the Blowfish block cipher, making use of it's expensive key setup to slow the algorithm down.
相关文章