SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    SitePoint Wizard donboe's Avatar
    Join Date
    Jun 2010
    Location
    Netherlands
    Posts
    2,165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Crypt password validation?

    For password storage, I always used MD5 hash. i.e.
    PHP Code:
    $username = isset($_POST['username']) ? $_POST['username'] : '';
    $password = isset($_POST['password']) ? $_POST['password'] : '';
    $hashed    md5($password);

    $q =  "INSERT INTO users (username,password)VALUES (:username,:hashed)"
    $data = array(':username' => $username, :hashed' => $hashed);
    $q->execute($data); 
    However, some members of the forum told me that this was not really safe. So I am trying to adjust.it . So instead of :
    PHP Code:
    $hashed    md5($password); 
    I use:
    PHP Code:
    $salt       'zandzeepsodemineraalwatersteenstralen'
    $hashed crypt($password'$2a$07$' $salt);
    $sql"INSERT INTO operators (v_naam, a_naam, username, password, salt) VALUES (:username,:hashed ,:salt)"
    The insert is working fine. The only problem I have is how to validate the password within the login function with the hashed password in combination with salt. When I still used MD5 I would use:
    PHP Code:
    $stmt->execute(array(':username' => $username'password' => md5($password))); 
    But how do I do that using salt and hased?

    Thank you in advance.
    “Good artists copy, great artists steal” (Pablo Picasso - 1934)

  2. #2
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,447
    Mentioned
    45 Post(s)
    Tagged
    13 Thread(s)
    Hi Donboe, how you doing?

    The best practice for password hashing in PHP is to use the built-in password_* functions (if you're using PHP 5.5 or higher) or the backwards compatibility library (for PHP 5.3.7 or higher).
    "There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies."

  3. #3
    SitePoint Wizard donboe's Avatar
    Join Date
    Jun 2010
    Location
    Netherlands
    Posts
    2,165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi fretburner. Thank you for the reply.

    Yes I am fine, and your self? I hope the people over there are not to upset after the dramatic lost of Brazil yesterday.

    I have been looking into the password_* functions especially at Example #3 password_hash() example setting salt manually. I tried this:
    Code:
    <?php
    $options = [
        'cost' => 11,
        'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
    ];
    echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
    ?>
    But I get a syntax error, 2 red marked lines in dreamweaver on the first line $options = [ and on the third line 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),

    And this is the first time I have been looking into this I don't knwo what is wrong or right. Is there no way that I can check the password in the old situation for the time beeing?
    “Good artists copy, great artists steal” (Pablo Picasso - 1934)

  4. #4
    Community Advisor bronze trophy
    fretburner's Avatar
    Join Date
    Apr 2013
    Location
    Brazil
    Posts
    1,447
    Mentioned
    45 Post(s)
    Tagged
    13 Thread(s)
    Quote Originally Posted by donboe View Post
    Yes I am fine, and your self? I hope the people over there are not to upset after the dramatic lost of Brazil yesterday.
    I'm doing well thanks. They're pretty disappointed about it, but I don't think many people were expecting Brazil to win.

    Quote Originally Posted by donboe View Post
    I have been looking into the password_* functions especially at Example #3 password_hash() example setting salt manually. I tried this:
    Code:
    <?php
    $options = [
        'cost' => 11,
        'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
    ];
    echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
    ?>
    I'd stick with the recommendation in the manual and let the function generate the salt for you automatically (Example #1) unless you have a specific reason not to. Note that the salt is part of the returned string, so you don't need a separate field for it in the DB.

    Quote Originally Posted by donboe View Post
    But I get a syntax error, 2 red marked lines in dreamweaver on the first line $options = [ and on the third line 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)
    In the first case, I expect your version of Dreamweaver doesn't recognise the short array syntax. As for the second error I'm not sure, but it's probably for similar reasons. Your code should still run OK.
    "There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies."

  5. #5
    SitePoint Wizard donboe's Avatar
    Join Date
    Jun 2010
    Location
    Netherlands
    Posts
    2,165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi fretburner. Thanks again for the reply. I will for sure have a look into this tomorrow
    “Good artists copy, great artists steal” (Pablo Picasso - 1934)

  6. #6
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,314
    Mentioned
    19 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by fretburner View Post
    Hi Donboe, how you doing?

    The best practice for password hashing in PHP is to use the built-in password_* functions (if you're using PHP 5.5 or higher) or the backwards compatibility library (for PHP 5.3.7 or higher).

    ...

    I'd stick with the recommendation in the manual and let the function generate the salt for you automatically (Example #1)
    +1
    "First make it work. Then make it better."

  7. #7
    SitePoint Wizard donboe's Avatar
    Join Date
    Jun 2010
    Location
    Netherlands
    Posts
    2,165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For some reason I am struggling to make this work. I try to follow the advise from fretburner using the build-in password function I have no problem hashing the password, i.e.
    PHP Code:
    $hash password_hash("$password"PASSWORD_DEFAULT).; 
    I rather have problems verifying the password in my function: This is how it was before fretburner adviced me to use the build in function:
    PHP Code:
     $salt 'zandzeepsodemineraalwatersteenstralen'
    $hash crypt($password'$2a$07$' $salt); 
    As you can see did I use a separated salt and hash. For verifying I used:
    PHP Code:
    function attempt($username$password){
        global 
    $pdo;
        
        
    $stmt $pdo->prepare('
            SELECT *
            FROM   operators
            WHERE  username = :username AND password = :password
            LIMIT 1'
    );
            
            
    $stmt->execute(array(':username' => $username':password' => crypt($password'$2a$07$' $salt)));    

        if (
    $data $stmt->fetchPDO::FETCH_OBJ )) {
            
    # set session
            
    $_SESSION['user_id']     = $data->user_id;
            
    $_SESSION['user']          = $data->v_naam;
            
    $_SESSION['username'] = $data->username;
            return 
    true;
        } else {
            return 
    false;
        }

    So where I have problems with is this part:
    PHP Code:
    ':password' => crypt($password'$2a$07$' $salt
    How do I accomplish the same using password_verify

    Thank you in advance
    “Good artists copy, great artists steal” (Pablo Picasso - 1934)

  8. #8
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,314
    Mentioned
    19 Post(s)
    Tagged
    1 Thread(s)
    Rather than comparing the password in SQL, you'll have to always fetch the user and compare the password in PHP.

    Code:
    function attempt($username, $password){
        global $pdo;
    
        $stmt = $pdo->prepare('
            SELECT *
            FROM   operators
            WHERE  username = :username
            LIMIT 1');
    
            $stmt->execute(array(':username' => $username));
    
        if ($data = $stmt->fetch( PDO::FETCH_OBJ )) {
            if (password_verify($password, $data['password'])) {
                # set session
                $_SESSION['user_id']     = $data->user_id;
                $_SESSION['user']          = $data->v_naam;
                $_SESSION['username'] = $data->username;
                return true;
            } else {
                // The password didn't match
                return false;
            }
        } else {
            // The username doesn't exist in the database
            return false;
        }
    }
    EDIT: The reason you need to do it this way is because you need to read the stored password hash (or, more specifically, the salt and cost stored with the password hash) in order to generate the verification hash.
    "First make it work. Then make it better."

  9. #9
    SitePoint Wizard donboe's Avatar
    Join Date
    Jun 2010
    Location
    Netherlands
    Posts
    2,165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Jeff. Thank you very much for the reply and the explanation. I have one last question. I just implemented your changes but suddenly get the following error:

    Cannot use object of type stdClass as array

    What can that be?
    “Good artists copy, great artists steal” (Pablo Picasso - 1934)

  10. #10
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,314
    Mentioned
    19 Post(s)
    Tagged
    1 Thread(s)
    Ahh, my fault. $data['password'] should actually be $data->password
    "First make it work. Then make it better."

  11. #11
    SitePoint Wizard donboe's Avatar
    Join Date
    Jun 2010
    Location
    Netherlands
    Posts
    2,165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    Ahh, my fault. $data['password'] should actually be $data->password
    Thank you very very much Jeff. Works great.
    “Good artists copy, great artists steal” (Pablo Picasso - 1934)


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •