10

像大多数用户一样,我只是想找出一种安全的方式来存储密码。我在这里没有找到(或者可能是我缺乏理解)是如何在我的数据库中检索加盐散列并将盐与散列密码分开,特别是在将盐+密码保持在一个单列。

我正在从 PHP 手册中找到所有这些很酷的密码加密方法(SHA-256,但 MySQL 是否只支持 SHA/1 和 MD5?)以及其他内容,但不确定如何存储和检索密码。

所以,到目前为止,这就是我所理解的:

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

在那之后,我迷失了盐分。

不加盐检索密码很容易,但盐让我很困惑。我在哪里可以再次从 $salt 获得价值,特别是如果它是唯一且安全的?我是否将它们隐藏在另一个数据库中?恒定(似乎不安全)?

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

4

2 回答 2

5

首先,您的 DBMS (MySQL) 不需要任何对加密哈希的支持。您可以在 PHP 端完成所有这些工作,这也是您应该做的。

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

// 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 散列解决方案,其中使用了加盐处理。

您绝对应该看看 WolfOdrade 链接到的问题的答案。

于 2010-07-17T21:41:48.033 回答
0

我个人建议让 MySQL 用它的内置函数来做这件事。

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

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'";
于 2010-07-18T04:03:41.937 回答