用PHP和MySQL腌制我的哈希

时间:2010-07-17 21:10:54

标签: php mysql security salt

与大多数用户一样,我只是想找出一种存储密码的安全方法。我在这里找不到的(或者可能是我缺乏理解)是如何在我的数据库中检索盐渍哈希并将盐与哈希密码分开,特别是,每个密码都有唯一的盐将salt +密码保存在一个列中。

我发现所有这些很酷的方法来加密密码(SHA-256,但MySQL只支持SHA / 1和MD5吗?)以及PHP手册中的其他内容,但不确定如何存储和检索密码。 / p>

所以,这就是我所理解的:

SHA('$salt'.'$password') // My query sends the password and salt 
                         // (Should the $salt be a hash itself?)

之后,我迷失了盐。

在没有盐的情况下检索密码很容易,但盐让我感到困惑。我从哪里再次获得$ salt的价值,特别是如果它独特且安全的话?我将它们隐藏在另一个数据库中吗?常数(似乎不安全)?

编辑: HMAC中的关键变量应该是盐还是其他的?

3 个答案:

答案 0 :(得分:5)

首先,您的DBMS(MySQL)不需要对加密哈希值有任何支持。你可以在PHP方面做到这一切,这也是你应该做的。

如果要在同一列中存储salt和hash,则需要将它们连接起来。

// the plaintext password
$password = (string) $_GET['password'];

// you'll want better RNG in reality
// make sure number is 4 chars long
$salt = str_pad((string) rand(1, 1000), 4, '0', STR_PAD_LEFT);

// you may want to use more measures here too
// concatenate hash with salt
$user_password = sha512($password . $salt) . $salt;

现在,如果您要验证密码,请执行以下操作:

// the plaintext password
$password = (string) $_GET['password'];

// the hash from the db
$user_password = $row['user_password'];

// extract the salt
// just cut off the last 4 chars
$salt = substr($user_password, -4);
$hash = substr($user_password, 0, -4);

// verify
if (sha512($password . $salt) == $hash) {
  echo 'match';
}

您可能需要查看phpass,它也使用此技术。它是一种PHP散列解决方案,在其他一些东西中使用salting。

你一定要看看WolfOdrade链接的问题的答案。

答案 1 :(得分:3)

这在前一篇文章中有详细介绍: Secure hash and salt for PHP passwords

答案 2 :(得分:0)

我个人建议让MySQL使用其内置函数执行此操作。

我这样做是为了在我的数据库配置文件中创建一个返回键字符串的函数。配置文件应位于您的站点根目录之外,以便Web服务器可以访问该文件,但不能访问其他文件。例如:

function enc_key(){
     return "aXfDs0DgssATa023GSEpxV";
}

然后在你的脚本中使用它与MySQL中的sql查询和AES_ENCRYPT和AES_DECRYPT函数,如下所示:

require_once('dbconf.inc.php');

$key = enc_key();

//When creating a new user
$sql = "INSERT INTO users (username, password) VALUES ('bob', AES_ENCRYPT('{$key}', {$password}))";

//When retrieving users password
$sql = "SELECT AES_DECRYPT('{$key}', password) AS password FROM users WHERE username like 'bob'";