#1
  1. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123

    Hashes and Salts


    I used to use plain md5 for my web app password store...then I read about the concept collissions so I stored the MD5 and the sha1 as the probablity of a collision of one matching both seems greatly reduced.

    Then I read about the concept of salts and started to use a salt...but using a single salt for all user passwords seemed a bit insecure and storing the salt alongside the password seemed equally insecure...if the list was leaked then so would the salts.

    I thought about salting the password with the database row id - seemed a bit too easy, the username? also an obvious choice.

    So I ended up doing this:

    PHP Code:
    $hash  sha1($password.md5(password)).md5($password.sha1($password)); 
    ie salting the password with the value obtained by a hash from another algorithm and then appending the same bit the algos switched.

    Given that I don't fully get the maths behind the algos is this approach sufficient to hamper the majority of attacks from a leaked list? or am I just simplifying the number of possibilities?

    Or should I just give up on hashes and move to encrypting passwords? But these can be decrypted. I can see the nature of attacks evolving but I've not been keeping up? Are these the biggest threats to security or should I be concentrating on something else first?

    Thanks!
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  2. #2
  3. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,119
    Rep Power
    9398
    I'm going to channel Jacques for a second and tell you that what you have now is not secure in the least. Salting with the password is better than not salting at all, but it is still not good enough as there can easily be hashed password lists constructed using the passwords themselves as salts.
    And while concatenating two different hashes greatly reduces the chance of a collision, all someone has to do is look at the 72 byte hash and realize that could be 32+40 (MD5+SHA1) or 40+32 (SHA1+MD5) and do a tiny bit of work on the list to break the hashes down into the pairs.

    Oh, and don't forget that even salted MD5 and SHA1 is still not secure so avoid them to begin with.

    Don't try to figure out your own scheme. Go with the tried and tested methods: a random* salt that varies for each password, and a good hashing algorithm like bcrypt. Don't need anything fancy, nor some combination of algorithms, nor a clever salting strategy.
    If you're not entirely sure what you're doing, password_compat or PHP 5.5+ can do it all for you, and do it right.

    As for encryption, the only possible reason one should ever encrypt passwords (as opposed to hash them) is because upper management has dictated that must be done and you've run out of every possible trick up your sleeve to show them how that's bad. Tricks such as pointing out how Adobe used encryption on their passwords but that still wasn't good enough. And the "user needs to be able to recover their password" excuse doesn't hold water because password resetting is commonly used and a well established practice.

    * Some people will tell you that you must use cryptographically secure salts that are resistant to complicated subjects like timing attacks. I disagree. The practically-built-in openssl_random_pseudo_bytes is perfectly fine to use (just remember that you probably need to base64_encode() it first - the function's output is binary and that doesn't work well in most salts).
  4. #3
  5. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    I'm not precious about the implementation, but what I'm looking for is:

    low collision probability
    difficulty in guessing hashing mechanism
    longer processing / 'slow' algorithms

    (the rest is down to better user password choice)

    and this is what I don't get:

    I can easily create random salts, but where/how do I store them?

    I'm running 5.4 at the moment, PHP5.5 should be fine (I'll worry about the upgrade in another thought process)
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  6. #4
  7. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Originally Posted by Northie
    low collision probability
    The problem of collisions is irrelevant for password hashing.



    Originally Posted by Northie
    difficulty in guessing hashing mechanism
    This is security by obscurity, and it is fundamentally wrong. The security of an algorithm must not depend on keeping it secret. This does not work. Many people (including big companies) have tried it, and they've all failed.

    You want the exact opposite: You want a mechanism everybody knows so that many experts have checked and tested it. The risk of screwing up some homegrown algorithm is much, much higher than the theoretical benefit of making the attacker guess the procedure. This again has been proven many times in reality.



    Originally Posted by Northie
    longer processing / 'slow' algorithms
    Yes.

    The criteria for choosing a password hash algorithm are the following:

    • established, widely used and accepted by a large majority of experts
    • computionally expensive with a variable(!) cost factor to account for improving hardware
    • built-in salt support to prevent multiple hashes from being attack at the same time
    • good support in PHP

    That leaves you with a single algorithm: bcrypt.



    Originally Posted by Northie
    I can easily create random salts, but where/how do I store them?
    bcrypt automatically stores the hash, the hash parameters and the salt in a single string.

    Contrary to popular belief, the salt does not have to be secret. Its only purpose is to make the hashing procedure unique for every password so that it's not possible to attack all hashes at once.



    Originally Posted by Northie
    I'm running 5.4 at the moment, PHP5.5 should be fine (I'll worry about the upgrade in another thought process)
    Whatever you do, use an established bcrypt library. Do not invent your own algorithm, do not create your own salt, do not use crypt() directly.

    You can basically choose between PHPass and the native password hashing API (or the password_compat library as a fallback for old PHP versions).

    The PHPass library is very established, and it has been written by the same person who wrote the low-level bcrypt implementation of PHP. However, it's a bit dusty, and it comes with a baggage of old algorithm to be used as a fallback.

    The native API or password_compat are more modern, but they currently have quite a lot of bugs, and I'm still waiting for the patches to be accepted.



    // A small addition:

    Your algorithm above has no salt at all. A salt is an additional random parameter which is generated per password. Your algorithm only takes a single parameter, the password. There's no such thing as "salting with the password" or a "constant salt".

    php Code:
    <?php
     
    function northieHash($password)
    {
        return sha1($password.md5($password)).md5($password.sha1($password));
    }

    This makes it trivial to break all hashes at the same time. This is in no way better than plain MD5. It might even be worse in case that your (mis)use of MD5 and SHA1 introduce cryptographic issues.
    Last edited by Jacques1; January 2nd, 2014 at 06:53 AM.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".

IMN logo majestic logo threadwatch logo seochat tools logo