【发布时间】:2013-09-28 22:35:36
【问题描述】:
我正在使用以下代码更新数据库中的密码和盐字段:
// First we execute our common code to connection to the database and start the session
require("common.php");
$id = $_GET[id];
// This if statement checks to determine whether the registration form has been submitted
// If it has, then the registration code is run, otherwise the form is displayed
if(!empty($_POST))
{
// Ensure that the user has entered a non-empty password
if(empty($_POST['password']))
{
die("Please enter a password.");
}
// Ensure that the user has entered a non-empty username
if(empty($_POST['confirmpassword']))
{
// Note that die() is generally a terrible way of handling user errors
// like this. It is much better to display the error with the form
// and allow the user to correct their mistake. However, that is an
// exercise for you to implement yourself.
die("Please confirm your password.");
}
if ($_POST["password"] == $_POST["confirmpassword"]) {
// An INSERT query is used to add new rows to a database table.
// Again, we are using special tokens (technically called parameters) to
// protect against SQL injection attacks.
$query = "UPDATE Staff SET password=:password, salt=:salt WHERE id=:id";
// A salt is randomly generated here to protect again brute force attacks
// and rainbow table attacks. The following statement generates a hex
// representation of an 8 byte salt. Representing this in hex provides
// no additional security, but makes it easier for humans to read.
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
// This hashes the password with the salt so that it can be stored securely
// in your database. The output of this next statement is a 64 byte hex
// string representing the 32 byte sha256 hash of the password. The original
// password cannot be recovered from the hash.
$password = hash('sha256', $_POST['password'] . $salt);
// Next we hash the hash value 65536 more times. The purpose of this is to
// protect against brute force attacks. Now an attacker must compute the hash 65537
// times for each guess they make against a password, whereas if the password
// were hashed only once the attacker would have been able to make 65537 different
// guesses in the same amount of time instead of only one.
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
try
{
// Execute the query to create the user
$stmt = $db->prepare($query);
$stmt->execute(array(
':password' => $password,
':salt' => $salt,
':id' => $id));
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// This redirects the user back to the login page after they register
header("Location: login.php");
}
die("Passwords do not match.");
}
数据库中有一个'id'字段,一个id等于1的员工(上一页的链接将id传递到这个页面,在这个例子中id是1)。我不确定它为什么不更新数据库。我是 php 新手,希望得到任何帮助。
谢谢, 乔
【问题讨论】:
-
您收到的错误信息是什么?
-
$id = $_GET[id];应该是$id = $_GET['id']; -
请使用真正的密码散列算法,例如PHP的
password_hash()函数提供的算法。sha256不适合密码哈希。 -
@SamT 说了什么。这是对 bcyrpt/PBKDF/类似的贫民窟尝试,远远达不到任何一个。
-
我知道这有点老套,但这只是一个测试。没有错误,只是没有更新