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

Php 如何在PDO中使用密码哈希使代码更安全?,php,mysql,security,pdo,password-hash,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 W

我的代码实际上正在工作,但它一点也不安全,我不想使用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>";
$dbh=newpdo('mysql:host='.DB_host';dbname='.DB_用户名、DB_用户名、DB_密码);
$username=$_POST[“username”];
$email=$_POST[“email”];
$password=$_POST[“password”];
$stmt=$dbh->prepare(“插入到用户集合用户名=”“$username.”,email=”“$email.”,password=”“$password.”);
$stmt->execute();
echo“谢谢,您已注册”


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

关于使代码更安全的问题:

  • 您应该始终验证用户条目,即使是来自POST方法,该方法可以在提交表单之前使用firebug进行更改。在查询中插入用户输入时,它更为重要
关于您的一般问题

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

您将在帐户创建时对用户名、密码和salt进行散列,并将散列插入数据库中

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

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


编辑:是的,密码\u散列也很好。

关于使代码更安全的问题

  • 您应该始终验证用户条目,即使是来自POST方法,该方法可以在提交表单之前使用firebug进行更改。在查询中插入用户输入时,它更为重要
关于您的一般问题

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

您将在帐户创建时对用户名、密码和salt进行散列,并将散列插入数据库中

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

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


编辑:是的,密码\u散列也很好。

基本上,您有两个选项,复杂性不同:

  • 使用您选择的散列算法存储注册用户密码的散列(稍后将详细介绍)
  • 创建一个随机salt(一个常量、秘密字符串),与用户密码一起使用,以如上所述创建哈希,然后将该哈希存储在DB中
检索用户记录时,将根据提供的密码计算的哈希值与数据库中存储的哈希值进行比较

例如:

$HashedPass = hash('sha512', $password);
或使用预定义的盐:

$HashedPass = hash('sha512', $password.SALT_STRING);
像以前一样将其存储到数据库中

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

$HashedPass = hash('sha512', $password.SALT_STRING);
然后根据与存储的哈希比较从数据库中检索

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

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


我希望您能发现,使用强大的散列算法以及Salt来减轻被盗散列数据库的损坏,这足以满足您的需要。

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

  • 使用您选择的散列算法存储注册用户密码的散列(稍后将详细介绍)
  • 创建一个随机salt(一个常量、秘密字符串),与用户密码一起使用,以如上所述创建哈希,然后将该哈希存储在DB中
检索用户记录时,将根据提供的密码计算的哈希值与数据库中存储的哈希值进行比较

例如:

$HashedPass = hash('sha512', $password);
或使用预定义的盐:

$HashedPass = hash('sha512', $password.SALT_STRING);
像以前一样将其存储到数据库中

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

$HashedPass = hash('sha512', $password.SALT_STRING);
然后根据与存储的哈希比较从数据库中检索

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

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


我希望您能发现,使用强大的散列算法以及Salt来减轻被盗的散列数据库的损害,足以满足您的需要。

只需使用库即可。认真地它们的存在是有原因的

  • PHP5.5+:使用
  • PHP5.3.7+:使用(上述的兼容包)
  • 所有其他:使用
不要自己做。如果你自己制作盐,你做错了。您应该使用一个为您处理该问题的库

$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
}

就用图书馆吧。认真地它们的存在是有原因的

  • PHP5.5+:使用
  • PHP5.3.7+:使用(上述的兼容包)
  • 所有其他:使用
不要自己做。如果你自己制作盐,你做错了。您应该使用一个为您处理该问题的库

$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
}
符合你的需要吗?关于合并,请检查两个哈希