I am try to offer the best password safety I can for my program, after some research all roads seem to end at PHPASS as my best option. I'm doing some experimental trials to understand what I'm doing. it's not going well lolAs far as I can see PHPASS adds a random salt to the password and then hashes it so it can then be stored in the DB, The user is now registered!.This works fine for me.It's this part I don't understand,when the user logs in I retrieve the hash from the DB and compare it to the hash that has been made from the password that the user has entered in the login but this time the new hash is different because it has been made from a different salt? and there for doesn't match the one stored in the DB.Somewhere I am being stupid and am missing something obvious that everyone else does get. Please help me as I seem to be retarded!
Not getting PHPASS
174 views Asked by Richard Harper AtThere are 3 answers
PHPASS returns a hash containing the algorithm used to calculate the hash, the cost of the hashing, the salt used, and what I assume is the result of the algorithm, and thus depends on the password used.
Algorithm:
For bcrypt hashes this should be '$2y$', although '$2x$' and '$2a$' are also possible. See PHP's manual entry on crypt(). (PHPASS uses crypt() if available I believe)
Cost:
A 2 characters wide zero padded value in the 04-31 range. 1<<<cost>
will be used internally, which is why 31 is the upper limit (32 bits available).
Salt:
22 characters from the alphabet "./0-9A-Za-z".
The remaining characters won't be used when using the hash as a salt.
Here is some code and its output that might clear up how it works when used correctly:
<?php
echo crypt('meow', '$2y$05$' . str_repeat('.', 20) . '//meow'), PHP_EOL; // salt: ....................//
echo crypt('meow', '$2y$05$' . str_repeat('.', 20) . '//woof'), PHP_EOL; // salt: ....................//
echo crypt('meow', '$2y$05$' . str_repeat('.', 20) . '//oink'), PHP_EOL; // salt: ....................//
echo PHP_EOL, '###########################', PHP_EOL, PHP_EOL;
echo $meow = crypt('meow', '$2y$05$' . str_repeat('.', 20) . '/meow'), PHP_EOL; // salt: ..................../m
echo $woof = crypt('meow', '$2y$05$' . str_repeat('.', 20) . '/woof'), PHP_EOL; // salt: ..................../w
echo $oink = crypt('meow', '$2y$05$' . str_repeat('.', 20) . '/oink'), PHP_EOL; // salt: ..................../o
echo PHP_EOL, '###########################', PHP_EOL, PHP_EOL;
echo crypt('meow', $meow), PHP_EOL; // salt: ..................../m
echo crypt('meow', $woof), PHP_EOL; // salt: ..................../w
echo crypt('meow', $oink), PHP_EOL; // salt: ..................../o
echo PHP_EOL, '###########################', PHP_EOL, PHP_EOL;
var_dump(
$meow === crypt('meow', $meow),
$woof === crypt('meow', $woof),
$oink === crypt('meow', $oink)
);
$2y$05$..................../.0/SFonSqiMg1jG/nWVk278LFl597ZlC
$2y$05$..................../.0/SFonSqiMg1jG/nWVk278LFl597ZlC
$2y$05$..................../.0/SFonSqiMg1jG/nWVk278LFl597ZlC
###########################
$2y$05$..................../eZ/qB29TfhKdQOwZTIrLyzBTMYOwupD6
$2y$05$..................../u45Ujx7ViT/dCkbXPqwsVuv407AA/99a
$2y$05$..................../eZ/qB29TfhKdQOwZTIrLyzBTMYOwupD6
###########################
$2y$05$..................../eZ/qB29TfhKdQOwZTIrLyzBTMYOwupD6
$2y$05$..................../u45Ujx7ViT/dCkbXPqwsVuv407AA/99a
$2y$05$..................../eZ/qB29TfhKdQOwZTIrLyzBTMYOwupD6
###########################
bool(true)
bool(true)
bool(true)
Thanks for your help peeps i seem to have it working now but if you would be so kind as to check it for me, if it's OK others may find it helpful, Please keep in mind it's only testing files so more will be added if the core is OK.
This is the REG code that hashes the password and stores it.
if(isset($_POST['submit'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_BCRYPT);
if (empty($_POST) === false){
mysql_query("INSERT INTO `accounts` VALUES ('', '$username', '$hash') ");
echo 'Done';
}else{
echo 'Not Done';
}
} ?>
And this is the Login
<?php
require('../password/lib/password.php');
require_once("connect.php");
if(isset($_POST['submit'])) {
$username = $_POST['username'];
$safe_username = mysql_real_escape_string($username);
$password = $_POST['password'];
$query = "SELECT * FROM accounts WHERE username = '$safe_username'";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
$hash = $row['password'];
if (password_verify($password, $hash)) {
echo 'Logged in';
} else {
echo 'Not logged in';
}
} else {
echo " Not submitted";
}
What do you think?
Yes, this is a good library to use. If you have PHP 5.5+ though, there is no need, as similar functionality is built in.
Use
$hasher->CheckPassword($pass, $hash)
to check the password, rather than rehashing it. This way it ensures it uses the same salt (the salt is stored at the start of the hash, as is the hash algorithm).