How to confirm password after encryption - php

So I've managed to encrypt the users password successfully and send it to the DB etc.. I just wanted to know how I would go about decrypting or other methods to check to see if the users input matches the DB password. Everytime the hash is processed a different encrypted password is created.Using PHP 4.3
<form method="post" action="">
<input type="text" name="user" id="user">
<input type="password" name="pass" id="pass">
<input type="submit" name="submit">
</form>
<?php
session_start();
require_once("connection.php");
require_once("passEncrypt.php");
if(isset($_POST["submit"])) {
$user = $_POST["user"];
$password = $_POST["pass"];
$pass = encrypt($password);
echo $pass;
}
?>
<?php
function encrypt($pass){
// use blowfish algorithm 10 times
$hash_format="$2a$10$";
$salt_length=22;
$salt = generate_salt($salt_length);
// store this in DB
$format_and_salt = $hash_format . $salt ;
$hash = crypt($pass, $format_and_salt);
return $hash;
}
function generate_salt($length){
// return 32 character random string
$unique_string = md5(uniqid(mt_rand(), true));
// provides valid characters
$base64_string = base64_encode($unique_string);
// replaces + with .
$mod_base64_string = str_replace('+', '.', $base64_string );
// make string correct length
$salt = substr($mod_base64_string, 0, $length);
return $salt;
}
?>
I realise the data isn't sanitized or the PHP secure etc.. I'm just trying to understand how to do this before I implement the code into my actual page.

First: This is not encryption. Encryption is reversible.
I wouldn't use this code at all:
<?php
function encrypt($pass){
// use blowfish algorithm 10 times # blowfish != bcrypt
$hash_format="$2a$10$";
$salt_length=22;
$salt = generate_salt($salt_length);
// store this in DB
$format_and_salt = $hash_format . $salt ;
$hash = crypt($pass, $format_and_salt);
return $hash;
}
function generate_salt($length){
// return 32 character random string
$unique_string = md5(uniqid(mt_rand(), true)); # Insecure RNG
// provides valid characters
$base64_string = base64_encode($unique_string);
// replaces + with .
$mod_base64_string = str_replace('+', '.', $base64_string );
// make string correct length
$salt = substr($mod_base64_string, 0, $length);
return $salt;
}
Instead, use the password hashing API. No reason to reinvent the wheel here.
$hash = password_hash($yourPassword, PASSWORD_DEFAULT);
if (password_verify($yourPassword, $hash)) {
// Login successful
}
Using PHP 4.3
Don't use PHP 4. If you do, you're totally on your own.

Related

recalling blowfish encryption w/ salt from database at login

I'm obviously new to blowfish encryption to be asking this. I believe to have one side of the equation figured out but cannot figure out how to login once the hash is in the DB. I have the following for encrypting the password on registration:
$blowfish_hash = "$2y$10$";
$salt_length = 22;
$salt = Generate_Salt($salt_length);
$hash_combined = $blowfish_hash . $salt;
$hash = crypt($password, $hash_combined);
$password = $hash;
The Generate_Salt() function is as follows:
function Generate_Salt($length) {
$unique_rndm_str = md5(uniqid(mt_rand(), true));
$base64_string = base64_encode($unique_rndm_str);
$mod_Base64_str = str_replace('+', '.', $base64_string);
$salt = substr($mod_Base64_str, 0, $length);
return $salt;
}
Once I register I get this nice long hash - great! but, when I go to login I'm unsure on how to call the hash to check against the given password: $_POST['log_password'];
Using md5 is was easy, I just encrypted this way $password = md5($password); and recalled this way $password = md5($_POST['log_password']); however reading up I realize that this is not a secure method.
I've been at this for hours, can anyone shed some light on this for me please? Any help would be appreciated.
ep
It is much easier than you think. Just use the function password_hash() instead, it will do the call to the crypt() function and handles the generation of a safe salt.
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($_POST['password'], PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($_POST['password'], $existingHashFromDb);

Getting hashes of different length

When I store my hashed password, it goes in as 29 characters, but when I hash for the password validation it is 64. The first 29 characters match, but I either need to lengthen the stored hash or shorten the validation hash. I have looked around the net and SO but can't seem to explicitly find out how to do this.
Which option (lengthen or shorten) is preferable and how would I go about doing this?
Here is my hash storage:
$hash = hash('sha256', $password1);
function createSalt(){
$text = md5(uniqid(rand(), true));
return substr($text, 0, 3);
}
$salt = createSalt();
$password = hash('sha256', $salt . $hash);
and here is my password validation and echoing of the hashes (which don't match up):
$userData = mysql_fetch_array($result, MYSQL_ASSOC);
$hash = hash('sha256', $userData['salt'] . hash('sha256', $password) );
if($hash != $userData['password']) // Incorrect password.
{ echo $userData['password'];
echo $hash;
die ('incorrect password : ' . mysql_error());
}
Thanks for any help, I sincerely appreciate it!

Hashing password using crypt does not work on the login it displays incorrect pass

I have a register page that allow user to insert password so i need to hash it to become more secure in the database this work fine
but when it come to the login the entered password do not match the register one how to fix this problemmm
this is my first time to use hash so it did not work as i want
This is the register code for hash:
//ADD MD5 hash to the password
function cryptPass($input, $rounds = 9)
{
$salt = "";
$saltChars = array_merge(range('A','Z'), range('a','z'), range('0','9'));
for($i = 0; $i<22; $i++)
{
$salt .=$saltChars[array_rand($saltChars)];
}
return crypt($input, sprintf('$2y$%02d$test$', $rounds) . $salt);
}
$hashedpass = cryptPass($pass1);
echo $hashedpass;
the hashing password = $2y$09$test$5I9x8HWhA4UHi5TMu.AxfdWvZadDCE.LD6HCkrK3ZsqJeN7e
This is the login code for hash:
function cryptPass($input, $rounds = 9)
{
$salt = "";
$saltChars = array_merge(range('A','Z'), range('a','z'), range('0','9'));
for($i = 0; $i<22; $i++)
{
$salt .=$saltChars[array_rand($saltChars)];
}
return crypt($input, sprintf('$2y$%02d$test$', $rounds) . $salt);
}
$hashedpass = cryptPass($pass);
echo $hashedpass;
the hashing password = $2y$09$test$4ZGgCiXdKzgQvuzwu.AxfdWvZadDCE.LD6HCkrK3ZsqJeN7e
Upon registration you create a unique salt. That salt is now part of the hash. If you look closely, you'll see it's embedded in the first part of the hash. To check the password, use the previous hashed password's salt, so you're using the same salt again.
$correctPasswordHash = getPasswordFromDatabase($_POST['username']);
$hash = crypt($_POST['password'], $correctPasswordHash);
if ($correctPasswordHash === $hash) ...
To make this easier and more foolproof, use the password_compat library, which wraps this in an easy to use API, which will also be integrated into a future version of PHP. Inspect its source code for the correct usage of crypt, since there are some pitfalls you need to take care of. The password_compat library is also using a custom binary comparison instead of a simple === to thwart timing attacks.
If I understand your code correctly, the login-time code is generating a fresh salt, ignoring the one that's stored with the password. Using different salts to hash the same password will generate different hashes.
Either use a constant salt pepper (scroll to the bottom of this answer), as per #c2's answer:
function cryptPass($input, $rounds = 9)
{
return crypt($input, sprintf('$2y$%02d$mysalt$', $rounds));
}
$hash = cryptPass($pass);
Or use the same salt both times:
// Login time (register-time code is unchanged)
function cryptPass($input, $salt, $rounds = 9)
{
return crypt($input, sprintf('$2y$%02d$%s$', $rounds, $salt));
}
function checkPass($freshPass, $hashFromDatabase) {
$salt = explode('$', $hashfromDatabase, 5);
$salt = $salt[3];
return cryptPass($freshPass, $salt) === $hashFromDatabase;
}

Site login with PHP MySQL Blowfish

I am having a serious issue with trying to validate my password when logging into my site. I am using php to create a blowfish encrypted password with salt using the code below.
<?php
function cryptPass($p, $rounds = 9) {
$salt = "";
$saltChars = array_merge(range('A','Z'),range('a','z'),range('0','9'));
for($i = 0; $i < 22; $i++){
$salt .= $saltChars[array_rand($saltChars)];
}
return crypt($p, sprintf('$2y$%02d$', $rounds) . $salt);
}
?>
This works fine and the crypted password is put into my mysql database. the problem is on login it will not validate. this is the login script.
if(isset($_POST["u"])){
// CONNECT TO THE DATABASE
include_once("php_includes/db_connect.php");
// GATHER THE POSTED DATA INTO LOCAL VARIABLES AND SANITIZE
$u = mysqli_real_escape_string($db_connect, $_POST['u']);
include_once("php_includes/hasher.php");
$p = (cryptPass($_POST['p']));
// GET USER IP ADDRESS
$ip = preg_replace('#[^0-9.]#', '', getenv('REMOTE_ADDR'));
// FORM DATA ERROR HANDLING
if($u == "" || $p == ""){
echo "login_failed";
exit();
} else {
// END FORM DATA ERROR HANDLING
$sql = "SELECT id, username, password FROM users WHERE username='$u' AND activated='1' LIMIT 1";
$query = mysqli_query($db_connect, $sql);
$row = mysqli_fetch_row($query);
$db_id = $row[0];
$db_username = $row[1];
$db_pass_str = $row[2];
if($p != $db_pass_str){
echo "login_failed";
exit();
} else {
//goto the users account
should I not be running the cryptPass function on the incoming user data?
Also of note would be that the mysql database password column is set up as VARCHAR(255) so its got plenty of room. At this point the password crypts right, I am just not able to compare it to the one in database properly. This is my first real try with blowfish pieced together from tutorials all over, I wanted to get away from md5 as php.net advises. Any help would be greatly appreciated. Thanks in advance for reading this.
Here's a slightly more in-depth demonstration as what's found on the PHP crypt() man page:
// Only for demonstration, see mcrypt_create_iv() for a better salt:
// http://php.net/manual/en/function.mcrypt-create-iv.php
$salt = substr(sha1(date('r')), rand(0, 17), 22);
$cost = 10;
$hash = '$2y$' . $cost . '$' . $salt;
$pass = 'mypass';
$notpass = 'notmypass';
$hashed = crypt($pass, "$hash");
echo "
Hash:
$hash
Hashed:
$hashed
Verified:
" . crypt($pass, $hashed) . "
Not Verified:
" . crypt($notpass, $hashed);
https://ignite.io/code/51323c3aec221e7b73000000
Which gives (at least this time):
Hash:
$2y$10$a80ded6289240c2e41a5e4
Hashed:
$2y$10$a80ded6289240c2e41a5euUFPvmt.sb6lBwOE.JTAdxQsDWmmM.Me
Verified:
$2y$10$a80ded6289240c2e41a5euUFPvmt.sb6lBwOE.JTAdxQsDWmmM.Me
Not Verified:
$2y$10$a80ded6289240c2e41a5euj06Emi8HigWM6BpqVFZ.ZtpA9wK5c8G
To verify the password you need the salt that was used to create the first password hash. This salt is included in the output string of the crypt() function, and crypt can extract this salt from the password hash.
You can see well how it works when you look at the new hash functions from PHP 5.5 password_hash() and password_verify()...
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
...the function that verifies the login password, needs the hash of the first password. It then can extract the salt and the cost factor from this string, to hash the login password with the same parameters.
I can recommend this new functions, there is a compatibility pack for earlier versions.

Login System Not Working PHP Hash

I am creating a login system. But for whatever reason I can't get the password to validate properly. It keeps telling me the password is wrong when I know the password is correct. Here is the form code:
<form id="login" action="login_processing.php" method="post">
<label2>Email</label2>
<input type="text" name="email">
<label2>Password</label2>
<input type="password" name="password">
<a class="forgot_password" href="forgot.php">Forgot password?</a>
<input type="submit" class="custom_submit" name="sign_in" value="Sign In">
<br />
<br />
<br />
Create Account
</form>
Here the code for processing the login information on login_processing.php:
require_once 'database_connect.php';
session_start();
$email = $_POST['email'];
$password = $_POST['password'];
$email = mysql_real_escape_string($email);
$findLogin = "SELECT password, salt FROM client_login WHERE email = '$email';";
$loginResult = mysql_query($findLogin);
if (mysql_num_rows($loginResult) < 1){
$_SESSION['errNo_account'] = 'No account with that email exists';
header('Location: login.php');
}
$userData = mysql_fetch_array($loginResult, MYSQL_ASSOC);
$hash = hash('sha256', $userData['salt'] . hash('sha256', $password));
if ($hash != $userData['password']){
$_SESSION['errPassword_incorrect'] = 'Incorrect Password';
header('Location: myaccount.php');
}
else{
$idSelect = "SELECT client_id FROM client_login WHERE email = '$email' ";
$idResult = mysql_query($idSelect);
while($idData = mysql_fetch_assoc($idResult)){
$_SESSION['client_id'] = $idData['client_id'];
}
}
Here is the original registration page hashing the password and adding salt:
function createSalt(){
$string = md5(uniqid(rand(), true));
return substr($string, 0, 3);
}
$salt = createSalt();
$hash = hash('sha256', $salt . $hash);
$insertLogin = "INSERT INTO client_login(email, password, salt, created) VALUES('$email','$hash', '$salt', '$today')";
mysql_query($insertLogin);
It keeps telling me that my password is incorrect... when I KNOW its not. I can't seem to figure out what the error is and ITS DRIVING ME NUTS!!!
Any help would be greatly appreciative.
in your registration script, you are using a single hash of the concated salt and pw, but in your login script you are using nested hash() calls.
registration:
$hash = hash('sha256', $salt . $hash);
login:
$hash = hash('sha256', $userData['salt'] . hash('sha256', $password));
notice the difference?
Here is where I messed up.. in my haste I never actually hashed the password to begin with when creating a new account. so it wasnt hashing anything.... just itself. So I added one line (to hash the original password) in the "new account" page and that fixed the whole issue:
function createSalt(){
$string = md5(uniqid(rand(), true));
return substr($string, 0, 3);
}
$hash = hash('sha256', $password); //this was forgotten originally :(
$salt = createSalt();
$hash = hash('sha256', $salt . $hash);
Now with that added the above code works fine. Thanks!

Categories