在基本的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>";
我是这样的n00b,简单的注册页面花了我两天时间。幼儿园的答案很受欢迎。
谢谢,
答案 0 :(得分: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>";
在现代,你应该使用 Blowfish / bcrypt 而不是MD5或SHA1。从PHP 5.3开始,您可以将crypt
与$2y$
前缀一起使用。从PHP 5.5开始,您将能够使用password_hash
代替。您可以同时使用ircmaxell's password_compat library。
以下是使用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>";
验证密码就像使用相同的参数重建哈希一样简单。
$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.";
}
答案 1 :(得分:1)
<?php
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = new PDOStatement();
$hash = sha1($pass . $dataUniqueToEachUser);
$stmt = $dbh->prepare("INSERT INTO Users(name, email, hash) VALUES (:name, :email, :hash)");
$stmt->bindParam(':name', $_POST['username'], PDO::PARAM_STR);
$stmt->bindParam(':email', $_POST['email'], PDO::PARAM_STR);
$stmt->bindParam(':hash', $hash, PDO::PARAM_STR);
$stmt->execute();
if ($stmt->rowCount() == 0) {
$valid = true;
}
}
catch (PDOException $e) {
echo "An error occurred: {$e}";
}
?>
答案 2 :(得分:0)
如果您想使用MD5进行哈希,可以在构造SQL语句之前使用密码执行以下操作:
$pass1 = md5($pass1);
$sql = "INSERT INTO contractors ( userid, password, name ) VALUES ( '$userid', '$pass1', '$name' )";
$result = $dbh->prepare($sql);
$count = $result->execute();
echo $count."<br>";
即使它是另一个哈希函数,这个想法也是一样的。在构造SQL语句之前散列密码。
由于Fiarr和VoteyDisciple已在下面的评论中注明,因此选择SHA哈希会更安全。
答案 3 :(得分:0)
使用这样的变量替换会使您的应用 wide 对SQL注入攻击开放,除非您在粘贴的代码之前转义$ userid和批次。
最好使用PDO的替换能力(我的意思是,你已经在调用.prepare):
$sql = "INSERT INTO contractors (userid, password, name) VALUES (?, PASSWORD(?), ?)";
$query = $dbh->prepare($sql);
$dbh->execute(array($userid, $pass1, $name));
我不确定内联PASSWORD()是否会起作用 - 如果我错了,请纠正我。如果你想采用Alan的方法而不是依赖MySQL来密码你的密码(明智的话),你也可以这样做:
$sql = "INSERT INTO contractors (userid, password, name) VALUES (?, ?, ?)";
$query = $dbh->prepare($sql);
$dbh->execute(array($userid, sha1($hashed), $name));
考虑使用盐:
$hashed = sha1("SaltedPassword" . $pass1);
答案 4 :(得分:-1)
如果你创建自己的哈希(也许更简单的硬盘),它可能更安全。在我看来,最好的解决方案是通过连接表中的几个字段来创建哈希,如下所示:
$pass1 = sha1($pass1.$name);
注意:md5,如上所述,并不是最安全的解决方案,因为目前互联网上有很多数据库都有与md5哈希变量相关的关键字,这使得想要破解你系统的人更容易。