Password verifying against database using bcrypt - php

Im trying to verify a password against the one in the database but it doesn't work.
Please see my code and let me know what's wrong.
Code for storing username and password to the database.
<?php
echo "enter the username \n";
$username = trim(fgets(STDIN));
echo "enter the password\n";
$password = trim(fgets(STDIN));
//connecting to database
$con=mysqli_connect("localhost","sqldata","sqldata","accounts");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$salt = substr(sha1(mt_rand()),0,22);
$hashedPassword= crypt($password , '$2y$10$' . $salt);
echo $hashedPassword;
mysqli_query($con,"INSERT INTO login (username, password)
VALUES ('$username', '$hashedPassword')");
mysqli_close($con)
?>
Code for verifying password is as follows
<?php
echo "enter the username \n";
$username = trim(fgets(STDIN));
echo "enter the password\n";
$password = trim(fgets(STDIN));
//connecting to database
$db = mysql_connect("localhost","sqldata","sqldata") or die(mysql_error());
//selecting our database
$db_select = mysql_select_db("accounts", $db) or die(mysql_error());
$result= mysql_query("select * from login where username = '$username' ");
if ( !$result ) exit( "$userName wasn't found in the database!" );
$row = mysql_fetch_array( $result );
$storedPassword = $row['password'];
$salt = substr(sha1(mt_rand()),0,22);
$hashedPassword= crypt($password , '$2y$10$' . $salt);
if (crypt($hashedPassword) == $storedPassword)
{
echo "ok";
}
else
{
echo "error";
}
?>

When you save you password to the database you are using:
$hashedPassword= crypt($password , '$2y$10$' . $salt);
but when you retrieve the password and check it I see a couple of things wrong:
$storedPassword = $row['password'];
$salt = substr(sha1(mt_rand()),0,22);
$hashedPassword= crypt($password , '$2y$10$' . $salt);
if (crypt($hashedPassword) == $storedPassword){/*...*/}
1, shouldn't:
$hashedPassword= crypt($password, '$2y$10$' . $salt);
be
$hashedPassword= crypt($storedPassword, '$2y$10$' . $salt);
2, It appears that you are using crypt twice:
$hashedPassword= crypt($password , '$2y$10$' . $salt);
if (crypt($hashedPassword) == $storedPassword)
so shouldn't is just be:
$hashedPassword= crypt($storedPassword, '$2y$10$' . $salt);
if ($hashedPassword == $storedPassword){/*...*/}

This is simpler than you are thinking. The crypt format is somewhat clever: it includes the salt as the start of the crypted password, in the form (method)(salt)(hash).
When using crypt(), it only looks at (method)(salt) and uses them to return (method)(salt)(hash), so to verify a password, all you need to do is pass the crypted password as the salt and see if the result matches. That is to say,
crypt($testPassword, $hashedPassword) === $hashedPassword

Related

PHP reset Password

I am confused about how to encrypt the new password to go in the database. When I enter the password it will encrypt and check the database correct and to verify for the new password it will just change it to plain text.
if (count($_POST) > 0) {
$result = mysqli_query($conn, "SELECT *from users WHERE id='" . $_SESSION["id"] . "'");
$row = mysqli_fetch_array($result);
if (MD5(mysqli_real_escape_string($_POST["currentPassword"] == $row["password"]))) {
mysqli_query($conn, "UPDATE users set password='" . $_POST["newPassword"] . "' WHERE id='" . $_SESSION["id"] . "'");
$message = "Password Changed";
} else
$message = "Current Password is not correct";
}
// password encryption for security.
$salt = mcrypt_create_iv(22, MCRYPT_DEV_URANDOM);
$salt = base64_encode($salt);
$salt = str_replace('+', '.', $salt);
$hash = crypt($pass, '$2y$10$'.$salt.'$');
//echo ("".$hash."<br />\n");
$pass is the password from the password input
save $hash to the database
verify the password with that got from the database $hash
if(password_verify($pass, $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
update and try that procedure
for simple application you can use base64_encode() to encrypt and store it into database when new password is entered. and for login also encrypt the entered password and match it with database.
your code:
if (count($_POST) > 0)
{
$result = mysqli_query($conn, "SELECT *from users WHERE id='" . $_SESSION["id"] . "'");
$row = mysqli_fetch_array($result);
$entered_password = base64_encode($_POST["currentPassword"]);
$new_password = base64_encode($_POST["newPassword"]);
$id = $_SESSION["id"] ;
if ($entered_password == $row["password"]))) {
$result = mysqli_query($conn, "UPDATE users set password='" . $new_password . "' WHERE id='" .$id. "'");
$message = "Password Changed";
} else
$message = "Current Password is not correct";
}
its a simply way.
//password encryption
$user_password = "1234";
$hash_pass = password_encryption($user_password, PASSWORD_BCRYPT, array('cost'=>10);
//"$user_password"-password obtained from the user input
//"$hash_pass" -encrypted password stored in a database
//verify the user password with that obtained from the database
if(password_verify($user_password, $hash_pass)){
echo "password is valid";
}else{
echo "password is not valid";
}
try this out.

Comparison between stored hashed password and hashed input password

I am currently doing log in system for my website,
I have 2 files which are
sign_up.php
function createSalt(){
$key = md5(uniqid(rand(), TRUE));
return substr($key, 0, 22);
}
$salt = createSalt();
$hash = hash("sha256", $password);
$password = hash("sha256", $salt.$hash);
$userLevel = '1';
$sql = "INSERT INTO users (username, email, password, salt, dob, userLevel)
VALUES (?,?,?,?,?,?)";
if ($stmt = mysqli_prepare($conn, $sql)) {
mysqli_stmt_bind_param($stmt, "sssssi", $username, $email, $password,
$salt, $birthdate, $userLevel);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
}
and sign_in.php
if (isset($_POST['username']))
$username = sanitize($_POST['username']);
if (isset($_POST['password']))
$password = sanitize($_POST['password']);
$sql = "SELECT *
FROM users
WHERE username = '$username'";
$queryresult = mysqli_query($conn, $sql);
if (!$queryresult)
echo "Unable to query table". mysqli_error();
else{
//get the data from database
while($row = mysqli_fetch_array($queryresult)) {
$salt = $row['salt']; //salt retrieved from the database
$dbpassword = $row['password']; //password retrieved from the database
$finalhash = hash("sha256", $password);
$finalhash1 = hash("sha256", $salt.$finalhash);
//check the password inputed by user to the database
if ($finalhash1 == $dbpassword){
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
echo "Hi $row[1], you are now logged in as $row[3]";
die ("<p><a href=administrator_page.php>Click here to continue</a></p>");
}
else
echo "<h2> Invalid username/password combination \n</h2>";
I don't know why my hashed password from user input always have extra value
I tried to echo it and this is the result:
f0b2dbf93305ce2eef8f5a1f45ab8b1046a7b9ba8ee2f305c3 --> stored password in mySQL
f0b2dbf93305ce2eef8f5a1f45ab8b1046a7b9ba8ee2f305c3f2fce10d5f199f --> inputed password from user
Can someone help me please? Really appreciate it thanks!

PHP login system with encryption (doesn't log in)

I'm struggling with an aspect of something I am trying to do. I am trying to create a basic password management system but I cannot login with an encrypted password. The password does get encrypted on the DB after using the account management page, but when I log out and try to log back in it no longer works.
Here is my code for the login page and change password page: I am aware that SQL injection is a problem but I haven't got round to sorting that part out yet.
LOGIN2.PHP
<link rel="stylesheet" type="text/css" href="default.css" media="screen"/>
<?php
session_start();
$dbname = "obsidian";
if(isset($_POST['sub'])){
//encryption for salt---------------------------------
function makeSalt($salt_length)
{ // only these characters are allowed in salt strings
$saltset = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
// note that this method only allows up to 6 duplicate chars
$saltchar = "$saltset$saltset$saltset$saltset$saltset$saltset";
// shuffles string randomly & grabs 1st n for our salt
$salt = substr(str_shuffle($saltchar), 0, $salt_length);
return $salt;
}
//Login Script
$username = $_POST['username'] ;
$password = $_POST['password'] ;
//ENCRYPTS THE USER ENTERED PASSWORD
$salt = '$5$rounds=1000$' . makeSalt(16) . '$';
$hashed_password = crypt($password, $salt);
//CONNECT TO DB
$mysqli = new mysqli('localhost','admin1', 'password1','obsidian' ) or die('Failed to connect to DB' . $mysqli->error );
$sSQL = "select * from users where password='$hashed_password' AND username='$username'";
$result = mysqli_query( $mysqli, $sSQL);
if (!$sSQL) {
printf("Error: %s\n", mysqli_error($con));
exit();
}
$row = mysqli_fetch_array($result);
if(!$row){
echo "<div>";
echo "No existing user or wrong password.";
echo "</div>";
session_destroy();
header("Location: index.php");
}
else {
$_SESSION['userid'] =$username;
header("Location: index.php");
}
}
?>
And this is the PHP script for the changing of passwords.
<?php
session_start();
$dbname = "obsidian";
if(isset($_POST['change'])){
//CREATE SALT-------------------------------------------------------------------------
function makeSalt($salt_length)
{ // only these characters are allowed in salt strings
$saltset = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
// note that this method only allows up to 6 duplicate chars
$saltchar = "$saltset$saltset$saltset$saltset$saltset$saltset";
// shuffles string randomly & grabs 1st n for our salt
$salt = substr(str_shuffle($saltchar), 0, $salt_length);
return $salt;
}
//Entered credentials from form---------------------------------------------------------
$oldPass = $_POST['oldPass'];
$newPass = $_POST['newPass'];
$newPassAgain = $_POST['newPassAgain'];
//Connect to DB-------------------------------------------------------------------------------
$mysqli = new mysqli('localhost','admin1', 'password1','obsidian' ) or die('Failed to connect to DB' . $mysqli->error );
//CHECK IF OLD PASS AND SESSION ID EQUAL-----------------------------------------------------
$sSQL = ("select * from users WHERE password='$oldPass' AND username= '" . $_SESSION["userid"] . "'");
$result = mysqli_query( $mysqli, $sSQL);
if (!$sSQL)
{
printf("Error: %s\n", mysqli_error($con));
exit();
}
$row = mysqli_fetch_array($result);
//IF THERE ARE NO ROWS, DO NOT CHANGE PASSWORD-------------------------------------------
if(!$row)
{
echo "<div>";
echo "No existing user or wrong password.";
header("Location: account.php");
echo "</div>";
session_destroy();
}
//IF THERE ARE ROWS ENCRYPT AND CHANGE PASSWORD----------------------------------------
else {
$salt = '$5$rounds=1000$' . makeSalt(16) . '$';
$hashed_password = crypt($password, $salt);
if ($newPass == $newPassAgain){
$update = ("UPDATE users SET password = '$hashed_password' where username= '" . $_SESSION["userid"] . "'") or die (mysql_error());
if ($mysqli->query($update) === TRUE) {
echo "Record updated successfully";
header("Location: success.php");
}
else {
echo "Error updating record: " . $mysqli->error;
}
}
}
}
A point in the right direction would be appreciated.
Thanks
You are hashing a password with a random salt each time.
Example code:
echo makeSalt(16) . "\n";
echo makeSalt(16) . "\n";
echo makeSalt(16) . "\n";
Outputs:
oAv0cGIzTECgF1gI
ypZegnQoS.d/inqA
6PPXZ/.YfupGuxPg
In order for the hash to be the same, the salt has to be the same. Though having the same salt for every user is not as secure as having a different hash for every user.
You could for example consider making the salt based on the username, or store the salt and the hash and then select the salt and encrypted password from the database for the user who is attempting to login.
Then the hash should match if you hash the supplied password with the same salt.
Furthermore, consider using sha_512 instead of sha__256. ($5$ -> $6$).
Also consider using mysqli or PDO as you will have more secure queries (Less chance on mysql injections).
(Pseudoish code)
(Insert code)
$salt = '$6$rounds=1000$' . makeSalt(16) . '$';
$hashed_password = crypt($password,$salt);
insert into table (password_salt,password_hash...) values($salt,$hashed_password,.....);
(Verify code)
select password_salt, password_hash.... from table where user = username
if(hash_equals(crypt($password,$password_salt),$password_hash)){
//OK
}else{
//Wrong password!
}
Your encryption system is safe and secure just as this
$user_input = "someone";
$pass_input = "something";
$auth_credentials = hash("sha512", md5(sha1(md5($user_input . $pass_input))));
echo $auth_credentials;
test and feedback.

Using prepared statement to retrieve login test info to $row parameter

I managed to achieve the result I wanted. After going over the PHP manual website yet another time. Personally I think that site makes things confusing for someone like myself that is trying to learn.
CODE (working):
<?php
include_once "lib\password.php";
//include_once "config.php";
$link = mysqli_connect("localhost", "root", "", "urlvaultdb");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
CRYPT_BLOWFISH or die ('No Blowfish found.');
$Blowfish_Pre = '$2y$10$';
$Blowfish_End = '$';;
$myusername = mysql_real_escape_string($_POST['myusername']);
$mypassword = mysql_real_escape_string($_POST['mypassword']);
$stmt = mysqli_prepare($link, "SELECT salt, password FROM users WHERE username = ?");
mysqli_stmt_bind_param($stmt, "s", $myusername);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $salt, $password);
mysqli_stmt_fetch($stmt);
mysqli_stmt_close($stmt);
$hashed_password = crypt($mypassword, $Blowfish_Pre . $salt . $Blowfish_End);
if ($hashed_password === $password) {
session_start();
$_SESSION['userid'] = $myusername;
header("location:index.php");
exit;
} else {
echo "Wrong Username or Password";
echo "<form action='index.php'>";
echo "<input type='submit' name='submit' value='Log-in'>";
echo "</form>";
}
/* close connection */
mysqli_close($link);
?>
Don't know if this will help you but i do something very similar using PDO but it should be along the same lines. I have a user enter their username and password and I use their username to get their user salt from the database.
For me, I prepend the salt to the users provided password then i hash it. I then check to see if the password provided by the user along with the salt and hash matches the password in the database return true or false.
//Select users row from database base on $email
$sql = 'SELECT * FROM users WHERE username = :userfield OR email = :userfield LIMIT 1';
$array = array(':userfield' => $_POST['myusername']);
$sth = $this->prepare($sql);
foreach ($array as $key => $value) {
$sth->bindValue("$key", $value);
}
$sth->execute();
$selection = $sth->fetchAll(PDO::FETCH_ASSOC);
//Salt and hash password for checking
$password = $selection[0]['user_salt'] . $_POST['mypassword'];
//hash the password
$password = $this->hashData($password);
// if there is a match return true otherwise return false
$match = ($password != $selection[0]['password'] ? false : true);

How to hash a password with random salt?

Here is my code for hashing a password with random salt. But unfortunately, it doesn't want to work, it gives an incorrect password.
Part one of the script where the user encodes his credentials.
<?php
echo "enter the username \n";
$username = trim(fgets(STDIN));
echo "enter the password\n";
$password = trim(fgets(STDIN));
//connecting to database
$con=mysqli_connect("localhost","sqldata","sqldata","accounts");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$salt = time();
$hashedPassword = sha1($password . $salt);
echo "$hashedPassword";
mysqli_query($con,"INSERT INTO login (username, salt, password)
VALUES ('$username', '$hashedPassword','$salt')");
mysqli_close($con)
?>
The second part of the script where the user enters his credentials.
<?php
echo "enter the username \n";
$username = trim(fgets(STDIN));
echo "enter the password\n";
$password = trim(fgets(STDIN));
//connecting to database
$db = mysql_connect("localhost","sqldata","sqldata") or die(mysql_error());
//selecting our database
$db_select = mysql_select_db("accounts", $db) or die(mysql_error());
$result= mysql_query("select * from login where username = '$username' ");
if ( !$result ) exit("$userName wasn't found in the database!");
$row = mysql_fetch_array($result);
$storedPassword = $row['password'];
$salt = $row['salt'];
$hashedPassword = sha1($password . $salt);
if ( $storedPassword != $hashedPassword ) {
exit( 'incorrect password!' );
} else {
echo "ok";
}
?>
You're storing the salt in the password column, and vice-versa.
mysqli_query($con,"INSERT INTO login (username, salt, password)
VALUES ('$username', '$hashedPassword','$salt')");
Changes this to:
mysqli_query($con,"INSERT INTO login (username, password, salt)
VALUES ('$username', '$hashedPassword','$salt')");

Categories