0

Possible Duplicate:
Secure hash and salt for PHP passwords

I'm currently a student and I aspire to become a great developer. I'm currently practicing how to properly encrypt and hash data to the database.

Here's my current implementation:

login_index.php

<?php

//Takes a password and returns the salted hash
//$password - the password to hash
//returns - the hash of the password (128 hex characters)
function HashPassword($password)
{
    $salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); //get 256 random bits in hex
    $hash = hash("sha256", $salt . $password); //prepend the salt, then hash
    //store the salt and hash in the same string, so only 1 DB column is needed
    $final = $salt . $hash; 
    return $final;
}

//Validates a password
//returns true if hash is the correct hash for that password
//$hash - the hash created by HashPassword (stored in your DB)
//$password - the password to verify
//returns - true if the password is valid, false otherwise.
function ValidatePassword($password, $correctHash)
{
    $salt = substr($correctHash, 0, 64); //get the salt from the front of the hash
    $validHash = substr($correctHash, 64, 64); //the SHA256
    echo $salt ."    salt" ."<br/> ";
    echo $validHash . " hash " ."<br/> ";
    echo $correctHash . " password " ."<br/> ";


    $testHash = hash("sha256", $salt . $password); //hash the password being tested

    //if the hashes are exactly the same, the password is valid
    return $testHash === $validHash;
}


?>

<?php
include 'login_config.php';
if(isset($_POST['login']))
{
    $password = $_POST['password'];
    $email = $_POST['email'];
    $Get_User = "Select * From users Where Email = '$email'";
    $hashed_password = "";
    $result = mysql_query($Get_User);
    if(mysql_num_rows($result) > 0)
    {
        while($row = mysql_fetch_array($result))
        {
            $hashed_password = $row['password'];

        }
    }


    $valid = ValidatePassword($password,$hashed_password);

    if($valid)
    {
        echo "<br/>";
        echo "Yes,Login successful";
    }
    else
    {
        echo "<br/>";
        echo "Oops,Wrong Email or Password";
    }
}
?>


<form action="" method="post">
Email: <input type="text" name="email" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" name="login" />
</form>

login_create.php

<form action="" method="post">
Firstname: <input type="text" name="fname" /><br />
Lastname: <input type="text" name="lname" /><br />
Email: <input type="text" name="email" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" name="save" />
</form>

<?php

include 'login_config.php';

function HashPassword($password)
{
    $salt = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); //get 256 random bits in hex
    $hash = hash("sha256", $salt . $password); //prepend the salt, then hash
    //store the salt and hash in the same string, so only 1 DB column is needed
    $final = $salt . $hash; 
    return $final;

}


if(isset($_POST['save']))
{
    $fname = $_POST['fname'];
    $lname = $_POST['lname'];
    $email = $_POST['email'];
    $password = HashPassword($_POST['password']);




    $insert = "Insert Into users (Fname,Lname,Email,Password) Values ('$fname','$lname','$email','$password')";
    $query = mysql_query($insert);

}


?>



</form>

I want to know how can I further improve my current implementation so that I further develop my skills and at the same time learn from experts/professionals. Do I somehow at least implement hashing properly?

Sir/Ma'am, your answers would be of great help and be very much appreciated. Thank you++

Community
  • 1
  • 1
Randel Ramirez
  • 3,543
  • 19
  • 47
  • 61
  • Looks fine, just usually you have one copy of the function stored in an included functions file. Makes edits much easier. – John V. Jun 11 '12 at 01:32
  • 1
    Storing the hash and salt in the same DB column doesn't reduce storage or processing too much; I'd personally separate them. As for the hashing itself, yours looks good, but if you're interested in other common hashing implementations, another is to do `md5(md5($password).$salt)`. – FThompson Jun 11 '12 at 01:34
  • @John Conde - In my current code, how do I prevent that? Thank you for the immediate response sir. – Randel Ramirez Jun 11 '12 at 01:38
  • 2
    @Vulcan: it looks odd when someone gives advice about `md5` when `sha256` is already used – zerkms Jun 11 '12 at 02:05
  • My personal preference for password hashing is `CRYPT_BLOWFISH`, also known as `bcrypt`. For practical reasons, I'd put the salt in an (adjacent) column, not concatenated, and use `crypt()`, which requires you to pass the salt in separately but also dictate the number of loops/iteratiosn that are performed on the password against the salt. I would not use the `SHA256` method directly (or any other); use the `CRYPT_` version, which is designed to be slow. Lastly, do NOT have two different pass hashing functions in different places. – Jared Farrish Jun 11 '12 at 02:08
  • @zerkms I believe you may have misread my comment. The OP wants to become a professional, so I let him know about another hashing algorithm he will most likely encounter in his career. – FThompson Jun 11 '12 at 02:13
  • @Vulcan: I'm sure he knows about md5, as long as he uses sha256. And just for information - `md5(md5($password).$salt)` - doesn't bring any additional protection in the comparison to the OP's original code – zerkms Jun 11 '12 at 02:18
  • @zerkms I never said, nor implied, that it did increase protection; please do not put words in my mouth. I simply commented about another hashing algorithm which is commonly used (i.e. in vBulletin, iPB). If you wish to continue this discussion, we may do so somewhere else. – FThompson Jun 11 '12 at 02:33

0 Answers0