如何在PDO中使用密码哈希来使我的代码更安全?

时间:2015-04-21 16:11:05

标签: php mysql security pdo password-hash

我的代码实际上正在运行,但它根本不安全,我不想使用MD5,因为它不是那么安全。我一直在查找密码哈希,但我不确定如何将其合并到我的代码中。

登录:

require_once __DIR__.'/config.php';
session_start();

$dbh = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_USERNAME, DB_USERNAME, DB_PASSWORD);

$sql = "SELECT * FROM users WHERE username = :u AND password = :p";
$query = $dbh->prepare($sql); // prepare
$params = array(":u" => $_POST['username'], ":p" => $_POST['password']);
$query->execute($params); // execute

$results = $query->fetchAll(); // then fetch


//hash passwords pls

if (count($results) > 0 ){
$firstrow = $results[0];
$_SESSION['username'] = $firstrow['username'];
echo "Hello $username you have successfully logged in";
//header ("location:.php");
}
else{
echo "Login Has Failed";
return;
} 

寄存器:

$dbh = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_USERNAME, DB_USERNAME, DB_PASSWORD);

$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];

$stmt = $dbh->prepare("insert into users set username='".$username."', email='".$email."', password='".$password."' ");
$stmt->execute();
echo "<p>Thank you, you are registered</p>";

有人能告诉我如何将它合并到我的代码中吗?

3 个答案:

答案 0 :(得分:22)

只需使用图书馆。认真。它们存在是有原因的。

不要自己动手。如果你正在创造自己的盐,你做错了。你应该使用一个为你处理这个问题的库。

$dbh = new PDO(...);

$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$hash = password_hash($password, PASSWORD_DEFAULT);

$stmt = $dbh->prepare("insert into users set username=?, email=?, password=?");
$stmt->execute([$username, $email, $hash]);

登录时:

$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $dbh->prepare($sql);
$result = $stmt->execute([$_POST['username']]);
$users = $result->fetchAll();
if (isset($users[0]) {
    if (password_verify($_POST['password'], $users[0]->password) {
        // valid login
    } else {
        // invalid password
    }
} else {
    // invalid username
}

答案 1 :(得分:2)

关于提高代码安全性

  • 您应该始终验证用户条目,即使是使用 POST 方法,也可以在提交表单之前使用firebug进行更改。在查询插入 用户输入时,这一点非常重要。

关于您的一般问题

正如我在评论中建议你的那样,使用PHPass或已经制作的API来为你完成这项工作。

您将在帐户创建时散列用户名,密码和salt,并在数据库中插入哈希值。

在身份验证时,您将使用给定的登录名+密码输入以及您为生成盐而添加的信息重新生成哈希。

如果两个生成的哈希都匹配,则对用户进行身份验证。

编辑:是的,password_hash也不错。

答案 2 :(得分:-1)

基本上,您有两种选择,复杂程度各不相同:

  • 使用您选择的哈希算法存储已注册用户密码的哈希值(稍后会详细介绍)。
  • 创建一个与用户密码一起使用的随机盐(常量,秘密字符串),以创建如上所述的哈希值,然后将该哈希值存储在数据库中。

检索用户记录时,将从提供的密码计算的哈希值与存储在数据库中的哈希值进行比较。

示例:

$HashedPass = hash('sha512', $password);

或使用预定义的SALT:

$HashedPass = hash('sha512', $password.SALT_STRING);

像以前一样将其存储到数据库中。

以类似方式进行身份验证:

$HashedPass = hash('sha512', $password.SALT_STRING);

然后根据与存储的哈希比较的数据库从数据库中检索。

现在,我想解决您对哈希算法的担忧: 您不必使用md5,您也可以使用更安全的哈希算法,请参阅此处的注释: PHP's hash function 一个建议是使用sha512算法。

最重要的是,您应该了解哈希是一种单向转换 - 没有实际的方法可以单独从哈希中对原始密码进行反向工程,也许只能找到生成相同字符串的替代字符串哈希字符串。

我希望你能找到一个强大的哈希算法,以及一个Salt来减轻被盗哈希数据库的损害,足以满足你的需求。