我怎样才能安全地存储我的用户密码?

这比普通的MD5更安全吗? 我刚开始研究密码安全。 我对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]!";
}

使密码存储方案安全的最简单方法是使用标准库

由于安全性往往比大多数程序员可以单独解决的要复杂得多,并且存在更多无形的可能性,所以使用标准库几乎总是最简单和最安全(如果不是唯一的话)可用选项。


新的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)。
它带有麻省理工学院许可证,所以即使在专有项目中,您也可以使用它。

使用Netsilik/PepperedPasswords的代码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已经在一些非常知名的项目中实现:

  • 。中文
  • WordPress 2.5+以及bbPress
  • Drupal 7版本(可用于Drupal 5和6的模块)
  • 其他
  • 好的是你不需要担心细节,这些细节已经由有经验的人编写,并由互联网上的许多人进行审查。

    有关密码存储方案的更多信息,请阅读Jeff的博客文章:您可能存储的密码不正确

    无论你做什么,如果你去'我会自己做,谢谢你'的方法, 不要再使用MD5SHA1 。 它们是很好的哈希算法,但出于安全目的考虑被破坏。

    目前,使用crypt和CRYPT_BLOWFISH是最好的做法。
    PHP中的CRYPT_BLOWFISH是Bcrypt哈希的实现。 Bcrypt基于Blowfish分组密码,利用昂贵的密钥设置来降低算法速度。


    如果您使用参数化查询而不是连接SQL语句,那么您的用户会更安全。 盐对每个用户都应该是唯一的,并且应该与密码哈希一起存储。


    更好的方法是为每个用户提供独特的盐。

    拥有一个salt的好处是,它使得攻击者更难预先生成每个字典单词的MD5签名。 但是如果攻击者知道你有一个固定的盐,他们可以预先生成每个字典词的MD5签名,前缀是你的固定盐。

    更好的方法是每次用户更改密码时,系统会生成随机盐并将该盐与用户记录一起存储。 它使得检查密码成本更高一些(因为在生成MD5签名之前你需要查找salt),但是这使得攻击者预先生成MD5变得更加困难。

    链接地址: http://www.djcxy.com/p/21531.html

    上一篇: How can I store my users' passwords safely?

    下一篇: How would you implement salted passwords in Tomcat 5.5