Password hash using various methods - php

I was looking for the best way to store the users' passwords, but I'm not really into security, so I've found a lot of information about encryption and things like that, using Google.
I don't like using snippets that I can get in blogs or sites on the Internet, I'd rather create my own solution, so I ended up developing two functions: One to create a hash and another one to check the "hashed" password.
I don't know if I'm doing right, or if I'm just increasing my problems, so take a look at the functions below.
// Creates a simple password's hash
function hashPassword( $password = false )
{
// Checks if the password has more than 6 characters
if( strlen( $password ) < 6 )
{
// Kills the script
exit('Password is too short.');
}
// Split the 4 first characters of the password
$salt = substr( $password, 0, 4 );
// Calculate the md5 hash of the salt
$salt = md5( $salt );
// Get the rest of the password
$password = substr( $password, 3, strlen( $password ) );
// Calculate the md5 hash of the password
$password = sha1( $salt . $password );
// Crypt the password
$password = crypt( $password );
return $password;
}
That's the password that I'm going to store. Now, check out the way I'm gonna check if the password's correct.
// Checks if a hashed password match a user input password
function checkHashedPassword( $password = false, $hashedPassword = false )
{
// Checks if the password has more than 6 characters
if( strlen( $password ) < 6 )
{
// Kills the script
exit('Password is too short.');
}
// Split the 4 first characters of the password
$salt = substr( $password, 0, 4 );
// Calculate the md5 hash of the salt
$salt = md5( $salt );
// Get the rest of the password
$password = substr( $password, 3, strlen( $password ) );
// Calculate the md5 hash of the password
$password = sha1( $salt . $password );
// Checks the password and hash
if( crypt( $password, $hashedPassword ) == $hashedPassword )
{
// Returns true
return true;
}
// Returns false by default
return false;
}
As you can notice, I'm going to create a variable storing the password, and the I can check if it's ok, like the code below:
$pass = hashPassword( $_POST['password'] );
if( !checkHashedPassword( $_POST['password'], $pass ) )
{
exit('Password incorrect!');
}
So, will it work securely?

If you are looking for a general and simple way Adding simple password hashing API is still in RFC for php but have very good implementation by ircmaxwell that you can use
Example
$hash = password_hash($password, PASSWORD_BCRYPT);
Verification
if (password_verify($password, $hash)) {
/* Valid */
} else {
/* Invalid */
}
Download Here

The Password Storage Cheat Sheet from OWASP provides good guidelines for password storage and hashing.
The key points are to use a strong salt, and iterate the hash (64,000 times or more currently).
A good and widely used PHP library for password hasing is the Portable PHP Password Hashing Framework by OpenWall, I recommend checking that out.

You can use:
$pass = <query password code>;
if( $pass != hashPassword( $_POST['password'] ); )
{
exit('Password incorrect!');
}

Related

login using PHP data object [duplicate]

I'm using PHP's password hashing API to hash and verify my passwords on a site I'm building, however whenever I try and verify my password it always returns false.
I have a User class which sets the password before they are inserted into the database:
public function set__password($passwd) {
self::$password = password_hash($passwd, PASSWORD_BCRYPT, array('cost' => 12));
}
If the username and email is unique the new user row is inserted - upon checking my database I have what seems to be a valid BCRYPT string for my password:
$2y$12$lTMEP0wevDEMX0bzStzoyOEzOTIAi3Hyhd3nYjGwzbI
To verify my password, I run the following script:
$username = $_POST['username'];
$password = $_POST['password'];
$DB = Database::getInstance();
// Get the stored password hash
$res = $DB->run__query('SELECT password FROM users WHERE username = "' . $username . '"');
$hash = $res[0]['password'];
// Do the passwords match?
if(password_verify($password, $hash)) {
echo 'success';
} else {
echo 'failed';
}
$hash pertains to the string quoted above, however when I then call password_verify($password, $hash) where $password is the plain-text password retrieved from my input field, I always receive a value of false.
The given hash string example has 50 characters instead of 60. Double-Check the database - CHAR(60) - and var_dump($hash).
Other problem that you can have, is when you reduce the cost in the server for gaining time.
Always use password_hash($pass, PASSWORD_DEFAULT), is the best way.

Website Protection- Am i doing it right?

I have some doubts about my security in my website, And i was wondering if I'm doing it correctly or not.
for POST\GET requests i always use mysqli_real_escape_string($connection,$2nd_parametter);
for Password Encryption i use password_hash('$password', PASSWORD_BCRYPT, array('salt' == 9));
People told me that BCRYPT is better than SHA for Website passwords.
for Login validation i use if($username === $db_username && $password === $db_password){};
for Pages accessibility check i use
if($_SESSION['role'] == 'Admin'){header("Location: admin");}}
else{header("Location: index");}
for Database connection mysqli_connect(localhost,root,,'database');
I do realize that this connection is vulnerable since there is no
password
I would like to know if there is any better way to do these protection steps effectively and easily and even making it way stronger.
1. mysqli_real_escape_string()
The escaping function is meant to insert user input into SQL-queries, not for usage in GET/POST requests. There is a better and more comfortable way though, you can use prepared statements, to protect from SQL-injection. To escape user input for HTML, the function htmlspecialchars() is better suited.
2. password_hash()
The password_hash() function should indeed be used, though it would be safer and more future proof to write it like this:
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
Your cost factor is a bit low and with PASSWORD_DEFAULT the algorithm could be changed in future should this be necessary.
3. if($username === $db_username && $password === $db_password)
This is actually not possible if you really used the password_hash() function, because of the random salt. Instead you have to check the password with:
$isPasswordCorrect = password_verify($password, $db_password);
4. if($_SESSION['role'] == 'Admin'){header("Location: admin");}}
Redirecting to protected pages is unsafe, nobody prevents an attacker to call the page directly. Each page has to check the permission on its own, if the logged in user should not see the page, then you can show the password form.
try this type
$input = "Yourpasswordtext";
$encrypted = encryptionIt( $input );
$decrypted = decryptionIt( $encrypted );
echo $encrypted . '<br />' . $decrypted;
function encryptionIt( $q ) {
$key = 'qJB0rGtIn5UB1xG03efyCp';
$encodestring = base64_encode( mcrypt_encrypt( MCRYPT_RIJNDAEL_256, md5( $key ), $q, MCRYPT_MODE_CBC, md5( md5( $key ) ) ) );
return( $encodestring );
}
function decryptionIt( $q ) {
$key = 'qJB0rGtIn5UB1xG03efyCp';
$decodestring = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, md5( $key ), base64_decode( $q ), MCRYPT_MODE_CBC, md5( md5( $key ) ) ), "\0");
return( $decodestring );
}

Password verify always returning true

I've been trying to write a simple login for a couple of days now. After I'd thought I had it working, I realized that it would accept any input in the password field as being true so I scrapped it and started again. I'm trying to use the php function password_verify for the verification but no matter what I do, it always returns true still. Is there something I'm doing wrong? Here is my code (I know it's not secure, I just want it to recognize a wrong password for now)
if(isset($_POST['submit']))
{
$username = $_POST['username'];
$password = $_POST['password'];
$hash = password_hash($password, PASSWORD_DEFAULT);
if(password_verify($_POST['password'], $hash))
{
echo 0;
}
else
{
echo 1;
}
}
The reason it always returns true is because you are verifying a hash that you just created... it will always be verified correctly.
When you use the password_verify() function the $hash parameter has to come from somewhere else (usually a database of some kind).
// If this is a POST request then handle the form
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Get password from form
$pass = filter_input(INPUT_POST, 'password', FILTER_UNSAFE_RAW);
// Connect to a database of some kind
// Get a previously hashed password
$hash = 'A HASH FROM SOMEWHERE ELSE...';
// Verify the previously hashed password
// against the password provided by the user
if (password_verify($pass, $hash)) {
echo 'Password is valid!';
}
}
You are $password getting a $_POST['password'];
You are hash a $password which is $_POST['password'];
password_verify($_POST['password'], $hash)
You are comparing a $_POST['password'] with a hash. the hash is also $_POST['password'].
That's why they return always true.because the $passwod,hash are $_POST['password'] is same.
You check the post password with the post password. You should check the post password instead with a wanted password.
You're assigning $hash to the password you received through POST.
This is how password_verify works
boolean password_verify ( string $password , string $hash )
Verifies that the given $hash matches the password received.
So now you're checking the password stored in $hash with the password obtained in POST which are the same.
Hence always true.

PHP Password verify always returns false

I'm using PHP's password hashing API to hash and verify my passwords on a site I'm building, however whenever I try and verify my password it always returns false.
I have a User class which sets the password before they are inserted into the database:
public function set__password($passwd) {
self::$password = password_hash($passwd, PASSWORD_BCRYPT, array('cost' => 12));
}
If the username and email is unique the new user row is inserted - upon checking my database I have what seems to be a valid BCRYPT string for my password:
$2y$12$lTMEP0wevDEMX0bzStzoyOEzOTIAi3Hyhd3nYjGwzbI
To verify my password, I run the following script:
$username = $_POST['username'];
$password = $_POST['password'];
$DB = Database::getInstance();
// Get the stored password hash
$res = $DB->run__query('SELECT password FROM users WHERE username = "' . $username . '"');
$hash = $res[0]['password'];
// Do the passwords match?
if(password_verify($password, $hash)) {
echo 'success';
} else {
echo 'failed';
}
$hash pertains to the string quoted above, however when I then call password_verify($password, $hash) where $password is the plain-text password retrieved from my input field, I always receive a value of false.
The given hash string example has 50 characters instead of 60. Double-Check the database - CHAR(60) - and var_dump($hash).
Other problem that you can have, is when you reduce the cost in the server for gaining time.
Always use password_hash($pass, PASSWORD_DEFAULT), is the best way.

Registered User password from DB and entered password during login do not match

I have registered a new user and saved the username, password & salt in the DB using the following hashing method:
if(isset($_POST['register']))
{
$password = $_POST['password']
function sanitize($data)
{
$data=trim($data);
$data=htmlspecialchars($data);
$data=mysql_real_escape_string($data);
return $data;
}
$password = sanitize($password);
function createSalt()
{
$salt = bin2hex(mcrypt_create_iv(32,MYCRYPT_DEV_URANDOM));
$hash = hash("sha256", $salt);
$final = $salt.$hash;
return $final;
}
$hashedPassword = hash("sha256", $password);
$salt = createSalt();
$hashedPassword = hash("sha256", $hashedPassword.$salt);
$query = sprintf("INSERT INTO users(username, password, salt) VALUES('%s','%s','%s')",$username, $hashedPassword, $salt);
}
And Later while trying the login.php, I am entering the same password which I saved during registration and using the below code to check if the entered password is the same as the one in the DB
if(isset($_POST['login']]))
{
$password = $_POST['password']
function sanitize($data)
{
$data=trim($data);
$data=htmlspecialchars($data);
$data=mysql_real_escape_string($data);
return $data;
}
function validateUser()
{
session_regenerate_id (); //this is a security measure
$_SESSION['valid'] = 1;
$_SESSION['username'] = $username;
}
$password = sanitize($password);
$query = sprintf("SELECT * FROM users WHERE username = '%s'",$username);
$sql = mysql_query($query);
$count = mysql_num_rows($sql);
$row = mysql_fetch_array($sql);
if($count<1)
{
echo $count;
unset($_POST['login']);
header("location:login.php");
exit;
}
$hash = hash("sha256", $password);
$salt = $row['salt'];
$hash = hash("sha256",$hash.$salt);
echo $hash."<br />".$row['password']."<br /><br />";
if($hash != $row['password'])
{
unset($_POST['login']);
header("location:login.php");
exit;
}
else
{
validateUser();
unset($_POST['login']);
header("location:index.php");
exit;
}
}
These passwords are not getting matched.
Kindly let me know what's wrong in this code.
There is nothing wrong with your code.
the salt value stored in the database is truncated because the varchar value is low increase the varchar value of your salt column to 200-300 something and than try this.. it will run fine.
I facepalmed when I found out this was screwing the result..
Dins
Actually i didn't see why this should not work, the code you have shown, should produce the same value, maybe you could check, whether the salt you read from the database is really the same as you wrote to the database.
Nevertheless i would not engourage to go further on this route, there are quite a lot of problems here.
First of all, SHA-256 is not a good choice to hash passwords, instead use a slow key-derivation function like BCrypt.
You should not escape input data without need, and if you need to escape them, you should do it only for the specific target system (htmlspecialchars and mysql_real_escape_string make no sense if you are going to calculate a hash anyway).
To create a salt, you use the random source, that is good. Using a hash afterwards creating the salt, will in no way make the salt more random.
There is no need to have two separate fields for password and salt in the database. Php's crypt() function will create a hash value, that already contains the salt.
I would invite you to read this tutorial about hashing passwords, you will find a PHP example too, and i would recommend to use the phpass library.

Categories