使用PDO准备语句插入密码哈希

Tom*_*Tom 3 php mysql pdo

在基本的mysql插入中,您可以设置密码变量'PASSWORD($ password)',但这会破坏PDO语句.

在使用pdo :: prepare和pdo :: execute时如何散列密码?

$sql= "INSERT INTO contractors (userid, password, name) VALUES ('$userid', '$pass1', '$name')";
$result = $dbh->prepare($sql);
$count = $result->execute();

Echo $count."<br>";
Run Code Online (Sandbox Code Playgroud)

我是这样的n00b,一个简单的注册页面花了我两天.幼儿园的答案很受欢迎.

谢谢,

Cha*_*les 14

注意

这个答案最初建议使用无盐哈希.现在这很愚蠢,所以它被重写以将其带入现代时代.在SO上的旧内容中注意类似的现在糟糕的答案.

您正在使用PDO,因此您应该使用带占位符的参数化查询:

$sql= "INSERT INTO contractors (userid, password, name) VALUES (?, ?, ?)";
$result = $dbh->prepare($sql);
$count = $result->execute(array($userid, $pass1, $name));

echo $count."<br>";
Run Code Online (Sandbox Code Playgroud)

在现代,你应该使用Blowfish/bcrypt而不是MD5或SHA1.由于PHP 5.3,你可以使用crypt$2y$前缀.从PHP 5.5开始,您将可以使用它password_hash.您可以同时使用ircmaxell的password_compat库.

这是一个使用的演示crypt非常低的难度值.请注意,我们还存储了盐.虽然我在本演示中对盐进行了硬编码,但您应该为每个用户使用一个独特的盐.

$salt = 'saltysaltsaltsalt'; 
$password_hash = crypt($pass1, '$2a$07$' . $salt);
$sql= "INSERT INTO contractors (userid, password, salt, name) VALUES (?, ?, ?, ?)";
$result = $dbh->prepare($sql);
$count = $result->execute(array($userid, $password_hash, $salt, $name));

echo $count."<br>";
Run Code Online (Sandbox Code Playgroud)

验证密码就像使用相同参数重建哈希一样简单.

$sth = $dbh->prepare('SELECT password, salt FROM contractors WHERE userid = ?');
$sth->execute(array($userid));
list($existing_hash, $salt) = $sth->fetch(PDO::FETCH_NUM);
unset($sth);

$new_hash = crypt($pass1, '$2a$07$' . $salt);
if($new_hash === $existing_hash) {
    echo "Password matched.";
} else {
    echo "Password did not match.";
}
Run Code Online (Sandbox Code Playgroud)