使用 PHP 和 MySQL 对我的哈希值加盐

发布于 2024-09-10 15:36:55 字数 556 浏览 9 评论 0原文

和大多数用户一样,我只是想找到一种安全的方式来存储密码。我在这里没有找到(或者可能是我缺乏理解)是如何在我的数据库中检索加盐哈希并将盐与哈希密码分开,尤其是每个密码都有唯一的盐,而将盐+密码维护在单个列中。

我从 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 中的关键变量应该是 salt 还是其他变量?

Like most users, I'm simply trying to figure out a secure way to store passwords. What I haven't found here (or maybe it's my lack of understanding) is how to retrieve a salted hash in my database and separate the salt from the hashed password, especially with unique salts to each password while maintaining the salt+password in a single column.

I'm finding all these cool ways to encrypt passwords (SHA-256, but does MySQL only support SHA/1 and MD5?) and other things from the PHP manual, but not sure how store and retrieve the passwords.

So, far this is all I understand:

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

After that I'm lost with salts.

Retrieving the password without a salt is easy, but the salt confuses me. Where do I get the value from $salt again, especially if it's unique and secure? Do I hide them in another database? Constant (seems unsafe)?

EDIT: Is the key variable in HMAC supposed to be salt or is this something else?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

追风人 2024-09-17 15:36:55

首先,您的 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 相关的问题的答案。

First of all, your DBMS (MySQL) does not need to have any support for cryptographic hashes. You can do all of that on the PHP side, and that's also what you should do.

If you want to store salt and hash in the same column you need to concatenate them.

// 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;

Now, if you want to verify a password you do:

// 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';
}

You might want to take a look at phpass, which also uses this technique. It is a PHP hashing solution which uses salting amongst some other things.

You should definitely take a look at the answer to the question WolfOdrade linked to.

此生挚爱伱 2024-09-17 15:36:55

我个人建议让 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'";

Personally I recommend letting MySQL do this with its built in functions.

They way I do this is to create a function in my database config file which returns a key string. The config file should be outside your sites root so that the webserver can access the file but not others. so for example:

function enc_key(){
     return "aXfDs0DgssATa023GSEpxV";
}

Then in your script use it with the sql query and AES_ENCRYPT and AES_DECRYPT functions in MySQL like this:

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'";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文