Jump to content

SHA1 password + salt problem - passwords not matching


Go to solution Solved by mac_gyver,

Recommended Posts

Hi again,

 

I have an add user form and a login form which both use a salt added to the password, then converted to a sha1 hash. 

 

Problem is, when I add the user, store the salt, and store the salted password, they're not matching when I try to log in. I am doing it the same both ways, as far as I can tell, so I'm not sure why the salted password would be different. Here are the code snips...

 

Add user: 

//Generate random 64 char salt.
    $salt = '';
    $characters="abcdefghijklmnopqrstuvwxyz0123456789";
    for ($i = 0; $i < 64; $i++) 
    {
        $salt .= $characters[rand(0, strlen($characters) - 1)];
    }  
    
    //Generate Salted SHA1 password hash
    $salted_password = sha1($salt.$password);

    //Add user to database
    
    $sql = "INSERT INTO users(fName, lName, username, password, salt, email) 
    VALUES (:fName, :lName, :username, :password, :salt, :email)";
                                          
    $stmt = $db->prepare($sql);
                                              
    $stmt->bindParam(':fName', $_POST['fName']);       
    $stmt->bindParam(':lName', $_POST['lName']); 
    $stmt->bindParam(':username', $_POST['username']);
    $stmt->bindParam(':password', $salted_password); 
    $stmt->bindParam(':salt', $salt);
    $stmt->bindParam(':email', $_POST['email']);                               
    $stmt->execute(); 

    //check if successful.
    IF ($db->lastInsertId())

This successfully stores the user information, the $salt.$password hash and the $salt itself. 

 

Now for login:

$password = $_POST['password'];
$username = $_POST['username'];

//Connect to database. Get Salt and Password.
$stmt = $db->prepare("SELECT * FROM users where username = :username");
$stmt->bindParam(':username', $username);
$stmt->execute();
$count= $stmt -> rowCount();
IF ($count==1)
{
    while ($row = $stmt->fetch()) 
    {
        $salt=$row['salt'];        
        $salted_password=sha1($salt.$password);
        echo "Password From Form: ".$password."<br>";
        echo "Salt from Database: " .$row['salt']."<br>";
        echo "Salt + password: ".$salted_password."<br>";
        echo "Database Password:".$row['password']."<br>";
        IF ($salted_password==$row['password']) 
        {
         $_SESSION['loggedIn']=1;
         echo "<h2>Logged In!</h2>";
        }
        ELSE
        {
            echo "<h2>Login Failed</h2>";
        }
    }
}

I cannot spot an error here... I am taking the username and password (which I echo'ed just to be sure the variable is correct, and compared sha1($salt.$password) to $row['password'] (previously saved as same sha1(salt.password) combination) but I only get a login failed result. 

 

I do not understand what I am doing wrong. I join $salt + $password and create an SHA1 hash from that., then I combine $salt + $password from login form and create an SHA1 hash from that as well, but end up with a different salted password hash. 

 

I have tried creating numerous users with different passwords, and each one has it's own salt in the database which corresponds to the salt being echoed when I try and log in... every one fails. Could someone be so kind as to point out where I am going wrong? Thank you. 

  • Solution

where in your add user code are you setting $password from the $_POST variable?

 

when you echo the two hashes and the salt in the log in code, is the salt the correct length and are the hashes completely different or do they start out the same, but the one from the database is missing characters on the end?

 

edit: also, why are you looping the in the log in code. you should have at most only one row for each user.

Please don't try to create your own password storage mechanisms. PHP 5.5 now comes with a purpose-built function for this, http://php.net/password_hash

 

If you can't use PHP 5.5, there is a backwards compatible library created by ircmaxell.

You 

 

where in your add user code are you setting $password from the $_POST variable?

 

when you echo the two hashes and the salt in the log in code, is the salt the correct length and are the hashes completely different or do they start out the same, but the one from the database is missing characters on the end?

 

edit: also, why are you looping the in the log in code. you should have at most only one row for each user.

 

You were correct, thank you - I didn't actually call the post data for the original $password. I thought I had it just under session at the top of the page but apparently had omitted it. I appreciate the help. 

 

As for not creating my own password mechanism, it works, and it works well, so I do not see any reason not to use it, personally. 

As for not creating my own password mechanism, it works, and it works well, so I do not see any reason not to use it, personally.

Because it does not work well at all. SHA1 is not made for hashing passwords, and it is easily bruteforced these days. For hashing passwords, you want a slow, adaptive algorithm. Adaptive means that as computers get faster, the algorithm gets stronger. SHA1 is not adaptive - as computers get stronger, it gets much, much weaker.

 

In addition, it's a very small change that you have to make which in turn makes your application much more secure. Kind of a no-brainer in my opinion.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.