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!
Related
we have existing user base on mysql with password encoded using md5 and sha1, with below logic -
// Password and salt generation
define('SALT_LENGTH', 9); // salt for password
function PwdHash($pwd, $salt = null)
{
if ($salt === null) {
$salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
} else {
$salt = substr($salt, 0, SALT_LENGTH);
}
return $salt . sha1($pwd . $salt);
}
Now when we check the for a valid user this is what we perform -
// $pwd is password encoded and stored in db
// $pass is the password coming from UI
if ($pwd === PwdHash($pass, substr($pwd, 0, 9))) {
// Perform something user is valid
}
Problem is the password coming from db doesn't match with the password coming from UI, however it works on server. Have tried multiple options without any success any pointer would really help.
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.
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.
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!
Is it a good way to change password value each time a user log in to the database?
I have wrote a hash function to hash the password when a user register a new account on the system.
Each time the user logs in, the hash value in the database will be changed. Is it good or bad?
If you designed this hash function all by your self then... It is a very very bad idea. Why would you need something like this? If you store salted SHA-256 hashed passwords the security is good enough. You do not need to regenerate passwords, it does not provide any additional security. If lets say your app is prone to SQL-Injection, then this scheme won't protect your app. You would be a lot better if you used salted and keyed SHA-256, something like this: (I'm not a php coder, I just want our apps to be secure)
$username = 'Admin';
$password = 'gf45_gdf#4hg';
$key = 'MySuperSecretKEY!!!!';
$salt = hash('sha256', uniqid(mt_rand(), true) . 'something random' . strtolower($username));
$hash = $salt . $password . $key;
$hash = hash('sha256', $hash);
$hash = $salt . $hash;
and then checking:
$username = 'Admin';
$password = 'gf45_gdf#4hg';
$sql = '
SELECT
`hash`
FROM `users`
WHERE
`username` = "' . mysql_real_escape_string($username) . '"
LIMIT 1
;';
$r = mysql_fetch_assoc(mysql_query($sql));
$salt = substr($r['hash'], 0, 64);
$hash = $salt . $password . $key;
$hash = hash('sha256', $hash);
$hash = $salt . $hash;
if ( $hash == $r['hash'] ) {
//OK
}
So even if attacker will be able to trick the salting algorithm he does not know, a key so he won't be able to reproduce a valid hash in SQL-Injection attack.