I try to understand how form, and password_hash and verify work. Here is the simple code that I wrote. The result that I get is "invalid Password"
What am I missing?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" name="pwd">
Password:
<table>
<tr>
<td><input name="passwd" type="text"/></td>
</tr>
<tr>
<td align="center"><br/>
<input type="submit" name="submit_pwd" value="hash"/>
</td>
</tr>
</table>
</form>
<?php
$passwd = $_POST['passwd'];
echo "Password : <BR>".$passwd."\n <BR>" ;
echo "Hash : <BR>".$hash = password_hash($passwd, PASSWORD_DEFAULT). "\n <BR>";
if (password_verify($passwd, $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
?>
</body>
</html>
Let me explain what is going (and not going) on here.
What the following does...
$hash = password_hash($passwd, PASSWORD_DEFAULT). "\n <BR>"
is an assignment, where you're trying hash a password, which will also contain a line break, a space and a <BR>
tag.
Then, trying to verify if the entered password matches the entered password, and a line break, and a space and <BR>
.
You should also be getting an undefined index notice about $passwd = $_POST['passwd'];
, so wrap that whole code in a conditional statement using the named submit input.
You will need to change your code to the following, while removing . "\n <BR>"
entirely.
if(isset($_POST['submit_pwd'])){
$passwd = $_POST['passwd'];
echo "Password : <BR>".$passwd."\n <BR>" ;
echo "Hash : <BR>".$hash = password_hash($passwd, PASSWORD_DEFAULT);
if (password_verify($passwd, $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
}
Here's a simple test using MD5 as an example in order to prove this, (note I didn't use password_hash()
here, since that produces a different hash and would be hard to actually prove the difference); code partially borrowed from http://php.net/manual/en/function.md5.php
Keep in mind that MD5 produces the same hash value.
$str_good = 'apple';
$str_bad = 'apple'. "\n <BR>";
echo md5($str_good); // produces 1f3870be274f6c49b3e31a0c6728957f
echo "<br>";
echo md5($str_bad); // produces cb2a3d3161fcc99dcf5e4ccd3bfbb14c
echo "<br>";
if (md5($str_good) === '1f3870be274f6c49b3e31a0c6728957f') {
echo "Would you like a green or red apple?";
}
You will notice that the assignment without the added . "\n <BR>"
produces a different value than the other.
"What am I missing?"
The fix is as simple as just removing . "\n <BR>"
which is "what is too much".