简体   繁体   English

正确的存储和检索SHA-256哈希密码和盐腌密码的方法

[英]Correct way to store and retrieve SHA-256 hashed and salted passwords

This is my first attempt in securely storing passwords and I would like to make sure that everything is done correctly. 这是我安全存储密码的第一次尝试,我想确保一切都正确完成。 I was advised to use SHA-256 hashing alongside salt. 建议我在使用Salt的同时使用SHA-256哈希。

Assuming user submitted their password thorough form, we get the password via 假设用户通过完整的表单提交了密码,我们将通过

$password = $_POST["password"];

What is correct way to salt $password and use SHA-256 hashing on it, so it can than be stored in a password field "password CHAR(64)" in a database? 什么是加注$ password并在其上使用SHA-256哈希的正确方法,因此可以将其存储在数据库的密码字段“ password CHAR(64)”中?

Once done and stored how would I than compare value stored in a database to one user entered in a login form? 完成并存储后,我如何将数据库中存储的值与登录表单中输入的一位用户进行比较? Lets assume $loginPassword = $_POST["loginPassword"]; 假设$loginPassword = $_POST["loginPassword"]; is what user entered. 是用户输入的内容。

Instead of using SHA family methods, you can use the crypt() function to salt it for you. 除了使用SHA系列方法,您还可以使用crypt()函数为您添加盐。

Here is an example script (save and login) using PDO. 这是使用PDO的示例脚本(保存和登录)。

Save password in DB 在数据库中保存密码

<?php
// Set the password
$password = 'mypassword';

// Get the hash, letting the salt be automatically generated
$hash = crypt($password);

echo $hash; // for testing purposes only

$mysql_username = 'username'; // for DB
$mysql_password = 'password'; // for DB

$dbh = new PDO('mysql:host=localhost;dbname=database_name', $mysql_username, $mysql_password);

$stmt = $dbh->prepare("INSERT INTO table_name (name,pass) VALUES (:name,:pass)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':pass', $pass);

// insert rows
// $name = $_POST['name'];
// $name = $_POST['pass'];

$name = "username";
$pass = $hash;
$stmt->execute();

Login script 登录脚本

<?php
$mysql_username = 'username'; // for DB
$mysql_password = 'password'; // for DB

$dbh = new PDO('mysql:host=localhost;dbname=database_name', $mysql_username, $mysql_password);

/*
$username = $_POST['username'];
$password = $_POST['password'];
*/

$username = "username";
$password = "mypassword";

$sql = "SELECT * FROM table_name WHERE name=:username";
$statement = $dbh->prepare($sql);
$statement->bindValue(':username',$username,PDO::PARAM_STR);

if($statement->execute())
{
    if($statement->rowCount() == 1)
    {
        $row = $statement->fetch(PDO::FETCH_ASSOC);

 if (crypt($password, $row['pass']) === $row['pass'])

        {
            $username = $row['name'];
            $email = $row['email'];

echo "Stage 1";

echo "<hr noshade size=\"1\">";

echo "Hello " .$username;

            exit;
        }
        else
        {
            // include "error_login.php";

echo "Stage 2 - ERROR";

        }
    }
    else
    {
       // include "error_login.php";

echo "Stage 3 error";
    }
}

If you're on PHP 5.5 or later, there's the built-in password_hash() and password_verify() with Bcrypt - if you're on PHP 5.3.7 or later, there's the password_compat compatibility library; 如果您使用的是PHP 5.5或更高版本,则具有Bcrypt的内置password_hash()和password_verify()-如果您使用的是PHP 5.3.7或更高版本,则具有password_compat兼容性库; all this is per the PHP.net Safe Password Hashing FAQ entry . 所有这些都是根据PHP.net安全密码哈希常见问题解答条目进行的

Essentially, on PHP 5.3.7 and above, replace the old crypt() with password_hash() and password_verify(). 本质上,在PHP 5.3.7及更高版本上,将旧的crypt()替换为password_hash()和password_verify()。

See my answer to PHP Secure password generation and storage for some more details on cost choice, but it boils down to the very simple: 有关成本选择的更多详细信息,请参见我对PHP Secure密码生成和存储的回答 ,但可以归结为非常简单的内容:

<?php
/**
 * In this case, we want to increase the default cost for BCRYPT to 12.
 * Note that we also switched to BCRYPT, which will always be 60 characters.
 */
$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>

to generate the hash, then you store the output string, and then verify with: 生成哈希,然后存储输出字符串,然后使用以下命令进行验证:

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>

Both examples come from the PHP.net Password Hashing page . 这两个示例均来自PHP.net密码哈希页面

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM