I'm trying to create an hashing function that, given a random salt, generates a password hash from it.
The problem is, that, if I enter the same password for two different users, the hash generated is the same for both.
Waht might be the problem?
public function generateSalt()
{
return $salt = substr(sha1(uniqid(rand(), true)), 0, 32);
}
public function pwdEncrypt($password, $salt)
{
$hash = crypt($password, '$2a$' . $salt . '$');
return $hash;
}
public function registerUser($nome, $email, $password, $permitions, $active)
{
$this->nome = $nome;
$this->email = $email;
$salt = $this->generateSalt();
$this->password = $this->pwdEncrypt($password, $salt);
//INSERT METHODS BELOW
}
That's not how you use crypt with blowfish ($2a$)
You need to specify the strength, and the salt at the end.
Try this crypt($password, '$2a$08$'.$salt);
Obviously increase the strength to improve security, at the expense of processing time.
I should also add, if you are using a PHP version greater than 5.3.7, you should use $2y$ for your blowfish algorithm, as an attack for $2a$ was discovered in 2011.
crypt() will return a hashed string using the standard Unix DES-based algorithm.
Standard DES-based hash has a two character salt from the alphabet "./0-9A-Za-z".
Since in your case the first three characters of the salt are always the same, the salt used is always the same.
Use
return $salt = substr(sha1(uniqid(rand(), true)), 0, 2);
and
$hash = crypt($password, $salt);
Related
I have two questions here :
Is it fine using the openssl_random_pseudo_bytes() for generating random string or is it only better to take strings directly from /dev/random?
I've written the below code to generate a unique salt and a salted hash for each users password now how do i verify the password? I am confused on how to authorize because the hashes are random due to salts presence.
For 1: See here: https://security.stackexchange.com/a/101117
It answers perfectly what you're looking for.
For 2: For checking the password. First, you need the salt to check it, so you need to store the salt somewhere. Make 3 functions out of it:
function getSalt($length = 33) {
return openssl_digest(openssl_random_pseudo_bytes($length), 'sha512')
. openssl_digest('intercept9', 'sha512');
}
function encrypt($salt, $password) {
$password = md5($pass . $salt);
return $password;
}
function verify($salt, $password, $hash) {
return encrypt($salt, $password) == $hash;
}
$salt = getSalt();
$hash = encrypt($salt, 'root');
var_dump(verify($salt, 'root', $hash));
But try to rely on the password_* functions php already has implemented.
i saw an example of password hashing using microtime() as this
public function create_hash($value)
{
return $hash = crypt($value, '$2a$12$'.substr(str_replace('+', '.', base64_encode(sha1(microtime(true), true))), 0, 22));
}
i want to know how could u can verify hash and make sure that the password entered by user is equal to the the password saved hashed in database while using microtime ?!
and that was the code for hash verify
private function verify_hash($password,$hash)
{
return $hash == crypt($password, $hash);
}
and how the last code works to verify hash ? ( the crypt method)
As of PHP 5.5, you can use password_hash() and password_verify() for hashing passwords much more conveniently than rolling with crypt().
To hash the password:
$hash = password_hash( $password, PASSWORD_DEFAULT );
Then to verify what the user has typed in against the hash:
if ( password_verify( $password, $hash )) {
// Password is good
}
So, I successfully encrypt a password to password hash using this following code :
class PassHash
{
// blowfish
private static $algo = '$2a';
// cost parameter
private static $cost = '$10';
// mainly for internal use
public static function unique_salt()
{
return substr(sha1(mt_rand()), 0, 22);
}
// this will be used to generate a hash
public static function hash($password)
{
return crypt($password, self::$algo .
self::$cost .
'$' . self::unique_salt());
}
// this will be used to compare a password against a hash
public static function check_password($hash, $password)
{
$full_salt = substr($hash, 0, 29);
$new_hash = crypt($password, $full_salt);
return ($hash == $new_hash);
}
}
and this is how I encrypting the password :
$password_hash = PassHash::hash($user->getPasswordHash());
But I have a little problem now when I try to display the password in normal mode.
What is the best way to decrypt the password from that hash ?
You can't decrypt a hash (well... technically you can, but you shouldn't) that's what hashes are for (not to be decrypted). You'll want to encrypt(hash) the password you received with the same hashing algorithm you used for the stored hash, and compare the hashes with eachother.
$password_hash = PassHash::hash($user->getPasswordHash());
if($stored_password === $password_hash){
//The passwords are the same
}
All in all you don't want to let anyone (not even yourself) know what the password of a user is (or the hash for that matter). The user will know, because he entered it and remembers it (hopefully anyway). No one else has got anything to do with seeing the user's password/hash. Letting anyone else but the user see/know the password/hash is a serious security issue.
On a different note: You should use the default implementations for hashing. Using your own hashing algorithm will always be worse than the true tried and tested methods. I'm not sure what PHP version you're using, but from PHP 5.5 onwards you can use password_hash(). For more information please view this question.
This is absolutely driving me crazy.
When registering an account I store the output of generateHash in the database.
I then generateHash again using the same $pattern when people try to log in.
However, the class generates a different hash. Even though I used the same pattern and password. This seems illogical.
class class_bcrypt
{
public function generateHash($pattern, $password)
{
//generate salt
$salt = '$2y$13$';
$salt = $salt . md5(strtolower($pattern));
//generate hash
$hash = crypt($password, $salt);
$hash = substr($hash, 29);
return $hash;
}
}
I am using this class in order to create password hashes. The system consist of a a webpage built upon php, iphone devices and also android devices. I need these smartphones to be able to log in and access the information stored in my DB server side. What is the best solution, is it to port this method to objective c and send the hash to the server? Or is it better to send the password using SSL and to compare the hash server side?
class PassHash {
// blowfish
private static $algo = '$2a';
// cost parameter
private static $cost = '$10';
// mainly for internal use
public static function unique_salt() {
return substr(sha1(mt_rand()),0,22);
}
// this will be used to generate a hash
public static function hash($password) {
return crypt($password,
self::$algo .
self::$cost .
'$' . self::unique_salt());
}
// this will be used to compare a password against a hash
public static function check_password($hash, $password) {
$full_salt = substr($hash, 0, 29);
$new_hash = crypt($password, $full_salt);
return ($hash == $new_hash);
}
}
"porting the hash" to the mobile apps would not be a good idea. The server's hash is unique, and you wouldn't want different "hash" methods across different device platforms.
Send the password in SSL and let your server-side authentication model do the hashing.