How to migrate from sha256 encryption to bcrypt for PHP? - php

For Login :
$rows = $sql->fetch(PDO::FETCH_ASSOC);
$us_id = $rows['id'];
$us_pass = $rows['password'];
$us_salt = $rows['password_salt'];
$status = $rows['attempt'];
$saltedPass = hash('sha256', "{$password}{$this->passwordSalt}{$us_salt}");
For Register :
$randomSalt = $this->rand_string(20);
$saltedPass = hash('sha256', "{$password}{$this->passwordSalt}{$randomSalt}");
How can this sha256 encryption method be converted to bcrypt?

Password Hashing Using bcrypt
If you are using PHP 5.5 or later, you can use the built-in password_hash() function with the $algo parameter set to PASSWORD_BCRYPT to create bcrypt hashes. You can use this as so:
$options = array('cost' => 11, 'salt' => 'my_salt');
$hash = password_hash("my_secret_password", PASSWORD_BCRYPT, $options);
Migration
It's not possible to do a bulk migration from sha256 to bcrypt because you need the original plaintext data (password) which isn't available.
Typically, sites do a staged conversion where you convert users as they perform successful logins. For example:
create a field in your database for password has type, sha256 or bcrypt
upon login, verify the password using the type in the database
if sha256 and successful, create a new bcrypt entry using the entered password, store that and update the password type to bcrypt. On the next login, bcrypt will now be used for verification.

Related

SHA512 and custom salt on checkhash - PhalconPHP

public function beforeSave(){
$salt = "Acrec_$";
$hashed = hash('sha512', $salt . $this->password);
$this->password = $hashed;
}
I'm using a custom Salt and custom hash to encrypt the users password, but, now i need to log-in the users.
the Code inside loginAction();
$this->auth->check([
'email' => $this->request->getPost('email'),
'password' => $this->request->getPost('password'),
'remember' => $this->request->getPost('remember')
]);
In phalcon just use:
$password = $this->request->getPost('password');
$user->password = $this->security->hash($password);
And
$password = $this->request->getPost('password');
$user = Users::findFirst();
if ($this->security->checkHash($password, $user->password)) {
// any logic here
}
By default it's using bcrypt which has salts built-in.
With PHP use password_hash and password_verify, the pair are secure and easy to use.
When saving a password verifier just using a hash function is not sufficient and just adding a salt does little to improve the security. Instead iterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Better yet use a function such as PBKDF2, Rfc2898DeriveBytes, password_hash, Bcrypt, passlib.hash or similar functions. The point is to make the attacker spend a substantial of time finding passwords by brute force.

sha256/salt password key storage

I have created a registration form processed as follows:
function register_user() {
global $conn;
$name = sanitize($_POST['name']);
$email = sanitize($_POST['email']);
$password = sanitize($_POST['password']);
$salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
$saltedPW = $password . $salt;
$hashedPW = hash('sha256', $saltedPW);
mysqli_query($conn, "INSERT INTO users (name, email, password, salt) VALUES ('$name', '$email', '$hashedPW', '$salt')");
The login form is then processed as follows:
function login($email, $password) {
global $conn;
$user_id = user_id_from_username($email);
$query = mysqli_query($conn, "SELECT salt FROM users WHERE email = '$email'");
$row1 = mysqli_fetch_assoc($query);
$salt = $row1['salt'];
$saltedPW = $password . $salt;
$hashedPW = hash('sha256', $saltedPW);
$result = mysqli_query($conn, "SELECT COUNT(user_id) FROM users WHERE email = '$email' AND password = '$hashedPW'");
$row = mysqli_fetch_row($result);
return ($row[0] == 1) ? $user_id : false;
}
The user table is structured as follows:
user_id; name; email; password; salt (additional columns for password recovering, admin rights, etc.). Having submitted the details to my company's IT compliance department, someone with PHP experience (exceeding mine no doubt) has stated that I can't store the key for the encryption in the system - if someone got the file they could decrypt the password. My question is - is this correct? Is my process flawed? All of the research I have carried out indicates that an SHA256 hash with random salt is one of the best ways to go.
I can't store the key for the encryption in the system
You haven't. You're hashing, you're not encrypting. salt !== key
if someone got the file they could decrypt the password
No. Nothing is encrypted, so there's nothing to decrypt. They'd get only the resulting hash, which they'd still have to brute force.
Is my process flawed?
Yes, but not because of their comments. It's flawed because you should never use SHA or MD5 or similar for passwords. They're designed to be fast, which is not what you want. You want something that intentionally takes a hunk of CPU, as to make brute force attacks untimely. This is exactly what the password_hash() function is for. Use it.
Do not use sha256,md5 etc for password hashing. I think you should use BCrypt for password hashing. This is the most powerful password hashing algorithm at present. password_hash() and password_verify() are used to hash and verify password for BCrypt. PHP 5.5.0 or greater uses BCrypt as default algorithm for password_hash(). Do not use your own salt. Let password_hash() do it for you.

How to compare a hashed password from user input?

I want my login password to be secured. So I came up to use the PHP's crypt() function to hash the password before inserting it to database. But Im having trouble when comparing the user input password from the converted hash password. Here's my code:
<?php
$password = 'hello_password';
# A higher "cost" is more secure
$cost = 10;
# Create a random salt
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');
# Blowfish algorithm.
$salt = sprintf("$2a$%02d$", $cost) . $salt;
$salted_password = $password . $salt; // apply salt to password
# hash the password
$hash_password = hash('sha256', $salted_password);
$userInput = 'hello_password'; // suppose this is the user input password
if (hash('sha256',$userInput) == $password) {
echo "Password Verified.";
}
else {
echo "Incorrect Password";
}
?>
But it always displays Incorrect Password although my password is correct. I don't want to use "hash_equals" function as it is not supported with my current PHP version. Can someone help me with this ? Thanks
You're comparing a hashed user input to the actual user password. So of course this is never going to work.
You're basically asking if hash == 'hello_password'. A hash will never match that, that is the whole point of a hash. You also aren't using the salt with the user input.
You hash the actual password with a salt which is fine:
$salted_password = $password . $salt; // apply salt to password
# hash the password
$hash_password = hash('sha256', $salted_password);
So you need to hash the user input with the salt, the same way:
$salted_input = $userInput . $salt; // apply salt to user input
# hash the input
$hash_input = hash('sha256', $salted_input);
Then you can compare $hash_input with $hash_password.
You also aren't using a salt properly. The salt is supposed to be used in the storage of the password to prevent rainbow table attacks. Randomly generating a salt to apply to both the input and the password at the time of comparison is pointless.

Hash with a salt in a function

i'm sorry for the bad use of English... I'm having a problem with making a function that hashes my password with a salt(first time using a salt).
The problem is that I don't know how to really return the salted/hashed password from the function.
My code:
# Password hashing with a salt.
function hashing($stringPassword)
{
// Making a random uniq code as salt.
$salt = uniqid(mt_rand(), true);
$HASH512 = hash('SHA512', $stringPassword);
$hashPassword = $salt.$HASH512;
return $stringPassword;
}
And how I tried to test it:
<?php
$stringPassword = '482301';
hashing($stringPassword);
echo $hashPassword;
?>
Thank you for helping!
Your code is backwards. The salt has to be part of the password BEFORE you hash it. and then you need to return the hashed password AND the salt, so that you can do proper comparisons later.
function hashing($cleartext) {
$salt = uniqid(mt_rand(), true);
$hash512 = hash('SHA512', $salt . $cleartext);
return(array('hash' => $hash512, 'salt' => $salt));
}
$foo = hashing('letmein');
echo "Salt is: $foo[salt]";
Since you are hashing passwords, you should be aware that the SHA* algorithms are not appropriate to hash passwords. They are much too fast, instead you need a function with a cost factor like BCrypt or PBKDF2 where you can control the necessary time for the calculation.
PHP offers a dedicated function password_hash() to generate BCrypt hashes, for earlier PHP versions you can use the compatibility pack:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// 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($password, $existingHashFromDb);

hashing password with salt

I have searched through Internet and found the function for hashing the password. But
i'm having trouble to deal with hashed password stored in the the database. the function i'm using generate the random password as it is concatenated with the random generated salt.
the problem comes when a user wants to change his password.
current_password = random hashed password( which must match the one stored in db).
if(current_password == $db_password){
enter new password
}
the above condition wont be true since the password is always random.
my function
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$', $rounds).$salt);
}
$pass = "password";
$hashedPass = cryptPass($pass);
echo $hashedPass;
i have 3 column in my user table (id, username, password).
can any one tell me how to properly use this function,
or is there a best way to do this?
You want to store the $salt generated in the database along with the hashed password. Then when you come to check the password you will be able to get the salt from the database and use it in the hashing process again.
So your database table with have an extra column in it called "salt"
(id, username, password, salt)
You need to do the same steps, as you would for the login. Check if the entered old password matches the password-hash in the database, then create a hash from the entered new password and store it.
PHP already has a function password_hash() to create a hash, and a function password_verify() to check whether the entered password matches the stored password-hash.
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// 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($password, $existingHashFromDb);
So your code would look something like this:
if (password_verify(current_password, $db_password))
{
enter new password
}

Categories