SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 44

Hybrid View

  1. #1
    SitePoint Zealot
    Join Date
    Mar 2007
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Hashing passwords

    I am creating a site that will have a login system and I would like to hash a users password before storing it in the database. My question is in case a user makes a simple password that could be figured out using brute force methods would it help to hash the password using md5 and sha1 like so:
    PHP Code:
    md5(sha1($Password)); 
    or would a salt that contains letters and numbers do the trick with just md5 like so:
    PHP Code:
    $Salt "64Mustang";
    md5($Password $Salt);; 
    Thanks in advance,
    Matt
    Kayzio - We don't hesitate, we accelerate.

  2. #2
    SitePoint Wizard triexa's Avatar
    Join Date
    Dec 2002
    Location
    Canada
    Posts
    2,476
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think using a salt definitely increases the security (a random string, not a word/number)

    but md5() and sha1() does also add a level, because at the second level it could be any number of hashes could be used...

    I'm interested to hear what others think in terms of level of security...
    AskItOnline.com - Need answers? Ask it online.
    Create powerful online surveys with ease in minutes!
    Sign up for your FREE account today!
    Follow us on Twitter

  3. #3
    Worship the Krome kromey's Avatar
    Join Date
    Sep 2006
    Location
    Fairbanks, AK
    Posts
    1,621
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If by "brute force" methods you are referring to an attacker gaining access to your database's list of hashed passwords and attempting rainbow lookups on them, then either method should adequately secure your users' passwords against this attack. Salting is a tried-and-true, time-honored and recognized method of making hashed data cryptographically secure; double-hashing using multiple algorithms, however, is one that, to my knowledge, has never cryptanalyzed, although logically it makes sense. Maybe combine the methods - salt, then hash, then salt again, then hash again - if you really want to, but salting alone will be sufficient, especially if each user has their own unique salt.

    If instead you mean someone sitting at their computer guessing obvious passwords ("password", "pword", "god"...), then nothing you do with a password (short of outright rejecting bad passwords) will secure your users' accounts should they choose such poor passwords.

    In my applications, I force users to use at least 2-3 classes of characters (where the "classes" are defined as being lower-case letters, upper-case letters, numbers, and symbols), and then each time the user changes their password (including the initial setting of their password) I give them a new random salt. One method I use for generating salts is:
    PHP Code:
    $salt md5(time()); 
    I've also written algorithms that choose from a wider array of possible characters (all 4 of the above-mentioned classes) to generate the salt. Since the user never needs to even see the salt, you can be as creative as you want with generating it.
    PHP questions? RTFM
    MySQL questions? RTFM

  4. #4
    SitePoint Addict
    Join Date
    Jan 2006
    Posts
    268
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Where do you store this per-user salt for later when you need to use it to verify log in information?
    If you give someone a program,
    you will frustrate them for a day;
    if you teach them how to program,
    you will frustrate them for a lifetime.

  5. #5
    SitePoint Wizard triexa's Avatar
    Join Date
    Dec 2002
    Location
    Canada
    Posts
    2,476
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pjleonhardt View Post
    Where do you store this per-user salt for later when you need to use it to verify log in information?
    If its unique per user, then just store it in another column
    AskItOnline.com - Need answers? Ask it online.
    Create powerful online surveys with ease in minutes!
    Sign up for your FREE account today!
    Follow us on Twitter

  6. #6
    SitePoint Zealot
    Join Date
    Mar 2007
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    With the time in the salt how do you go about doing that? When a user goes to log in at a later time does it pull the time of when they created the password from a database to recreate their salt for matching their password to the one in the database?
    Kayzio - We don't hesitate, we accelerate.

  7. #7
    SitePoint Wizard triexa's Avatar
    Join Date
    Dec 2002
    Location
    Canada
    Posts
    2,476
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Kayzio View Post
    With the time in the salt how do you go about doing that? When a user goes to log in at a later time does it pull the time of when they created the password from a database to recreate their salt for matching their password to the one in the database?
    I think Dan was just indicating a way a salt could be created.

    You could have a table called users..

    Username | Password | Salt

    You could set the salt when they create the account... personally I see no reason for it to ever change unless it has been compromised.

    $pass = md5('blah');
    select from users where MD5(CONCAT('$pass', Salt)) = MD5( CONCAT(MD5(Password), Salt )

    something like that... could obviously be changed and thats just off the top f my head
    AskItOnline.com - Need answers? Ask it online.
    Create powerful online surveys with ease in minutes!
    Sign up for your FREE account today!
    Follow us on Twitter

  8. #8
    SitePoint Zealot
    Join Date
    Mar 2007
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The only problem I see with this is if someone got access to the database and got the list of passwords they would also have the salt key.
    Kayzio - We don't hesitate, we accelerate.

  9. #9
    SitePoint Wizard triexa's Avatar
    Join Date
    Dec 2002
    Location
    Canada
    Posts
    2,476
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Kayzio View Post
    The only problem I see with this is if someone got access to the database and got the list of passwords they would also have the salt key.
    If someone gains access to your database... then they've got it all. You'd need to likely build a custom routine to encrypt the passwords. Some encryption algorithms may use a salt, others may not...

    This way the salt is in the code and as well the passwords are encrypted in a custom manner - so if it is done properly it would be even harder to crack
    AskItOnline.com - Need answers? Ask it online.
    Create powerful online surveys with ease in minutes!
    Sign up for your FREE account today!
    Follow us on Twitter

  10. #10
    SitePoint Addict
    Join Date
    Jan 2006
    Posts
    268
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thats my problem with it too. If you're storing the salt with the hash, the salt becomes pointless..

    Obviously, a per-user salt is more secure, if you can keep the salts secure but still accessible to your scripts..
    I'm not sure how to do that though, right now I keep one salt, in a file in the non public folder of my server that only my scripts have access to.
    If you give someone a program,
    you will frustrate them for a day;
    if you teach them how to program,
    you will frustrate them for a lifetime.

  11. #11
    SitePoint Zealot
    Join Date
    Mar 2007
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think I will use a single salt for all passwords which will be stored in my code, and use a few methods to hash the passwords so that they are more secure.
    Kayzio - We don't hesitate, we accelerate.

  12. #12
    SitePoint Wizard triexa's Avatar
    Join Date
    Dec 2002
    Location
    Canada
    Posts
    2,476
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Kayzio View Post
    I think I will use a single salt for all passwords which will be stored in my code, and use a few methods to hash the passwords so that they are more secure.
    Off the top of my head, there is [url=http://php.net/mcrypt]mcrypt[/php]

    Plus I'm sure phpclasses.org has PLENTY of encryption/hashing classes
    AskItOnline.com - Need answers? Ask it online.
    Create powerful online surveys with ease in minutes!
    Sign up for your FREE account today!
    Follow us on Twitter

  13. #13
    Worship the Krome kromey's Avatar
    Join Date
    Sep 2006
    Location
    Fairbanks, AK
    Posts
    1,621
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by triexa View Post
    Off the top of my head, there is [url=http://php.net/mcrypt]mcrypt[/php]

    Plus I'm sure phpclasses.org has PLENTY of encryption/hashing classes
    Two-way encryption of passwords is a bad idea that leaves your users vulnerable if they use the same username/password for other sites as well (and so very many do). If an attacker gains access to your server's filesystem (something that is depressingly easy to do in many shared hosting environments), then they have your database and your decryption key (since it must be in your scripts in plain text). Not to mention that a slight server misconfiguration could result in dumping your script as plain text, revealing your key as well as any possible security holes to gain access to the list of your users' passwords.
    PHP questions? RTFM
    MySQL questions? RTFM

  14. #14
    SitePoint Wizard triexa's Avatar
    Join Date
    Dec 2002
    Location
    Canada
    Posts
    2,476
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kromey View Post
    Two-way encryption of passwords is a bad idea that leaves your users vulnerable if they use the same username/password for other sites as well (and so very many do). If an attacker gains access to your server's filesystem (something that is depressingly easy to do in many shared hosting environments), then they have your database and your decryption key (since it must be in your scripts in plain text). Not to mention that a slight server misconfiguration could result in dumping your script as plain text, revealing your key as well as any possible security holes to gain access to the list of your users' passwords.
    A moment of ignorance if you will.. hehe. Definitely 2-way passwords is a bad idea.

    Scratch that
    AskItOnline.com - Need answers? Ask it online.
    Create powerful online surveys with ease in minutes!
    Sign up for your FREE account today!
    Follow us on Twitter

  15. #15
    Worship the Krome kromey's Avatar
    Join Date
    Sep 2006
    Location
    Fairbanks, AK
    Posts
    1,621
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Kayzio View Post
    I think I will use a single salt for all passwords which will be stored in my code, and use a few methods to hash the passwords so that they are more secure.
    Please please please read my last post before you run with this idea. This is an idea born of ignorance of salts, and I do not mean any disrespect at all - so very few people understand salts, and this has lead to the rapid propagation of this fallacy.
    PHP questions? RTFM
    MySQL questions? RTFM

  16. #16
    SitePoint Wizard triexa's Avatar
    Join Date
    Dec 2002
    Location
    Canada
    Posts
    2,476
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kromey View Post
    Please please please read my last post before you run with this idea. This is an idea born of ignorance of salts, and I do not mean any disrespect at all - so very few people understand salts, and this has lead to the rapid propagation of this fallacy.
    A salt stored in code definitely does increase security though. They don't have an additional (VITAL) piece of information to work with.

    If someone manages to get your code that has your salt in it as well as your users table, then shame on you and let me know so I NEVER sign up for anything of yours
    AskItOnline.com - Need answers? Ask it online.
    Create powerful online surveys with ease in minutes!
    Sign up for your FREE account today!
    Follow us on Twitter

  17. #17
    Worship the Krome kromey's Avatar
    Join Date
    Sep 2006
    Location
    Fairbanks, AK
    Posts
    1,621
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yup, triexa is spot on, although I never double-hash in my applications. Just to let you know how this thing works in my apps, I'll walk you through the whole process:

    User signs up:
    Code php:
    $salt = md5(time());
    $pass = md5($salt.$_POST['pass']);
    mysql_query("INSERT INTO users SET
        username='{$_POST['uname']}',
        pass='$pass',
        salt='$salt'");
    (Of course there would be validation of user input, and we'd make sure the chosen username is not already in use, but you get the idea.)

    Now the user table contains the username, the salted hashed password, and the salt. So when the user logs in:
    Code php:
    $res = mysql_query("SELECT pass,salt FROM users WHERE username='{$_POST['uname']}'");
    list($pass, $salt) = mysql_fetch_array($res);
    if(md5($salt.$_POST['pass'])==$pass)
        //user entered correct password
    Incidentally, this highlights another aspect of my apps: I never check passwords in the database itself, I always pull it out and check them in my app. This saves me from a potential SQL injection that I didn't defend against allowing someone to log in with any username they want.


    To address the concern of the Bad Guy(R) getting the salt, it doesn't matter. The salt is never meant to be secret. This is the most misunderstood aspect of salted hashes. The salt is there to negate the use of rainbow tables (a "rainbow table" is a table of all (or most) possible results of a hashing algorithm along with strings that result in that hash; Google it for more information), and the per-user salt is there to complicate brute-force attacks on the entire list of hashed passwords (if you use the same salt for every user, then someone who gets the entire list of hashed passwords can brute-force every password at once - generate a hash, check it against every password, see if anything matches). Per-user salts mean that an attacker has to attack each individual password one at a time, making the entire ordeal computationally infeasible.
    PHP questions? RTFM
    MySQL questions? RTFM

  18. #18
    SitePoint Enthusiast
    Join Date
    Sep 2006
    Posts
    37
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kromey View Post
    Incidentally, this highlights another aspect of my apps: I never check passwords in the database itself, I always pull it out and check them in my app. This saves me from a potential SQL injection that I didn't defend against allowing someone to log in with any username they want.
    I'm sure I've read this before but this time it really stuck. Thanks for the info!

  19. #19
    SitePoint Zealot
    Join Date
    Mar 2007
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK so here is my new plan:
    Hash passwords using md5 and sha1 with a salt that is created with a string stored in my code and the time the password is created which shall be stored in the database. This way if someone is able to get the database they are missing part of the salt needed to hash the password properly and if they gain access to my code they are missing the salt time which is stored in the database. Let me know what you all think of this plan.

    For Example:
    PHP Code:
    $Time time();
    $Salt "gfhsd456345" $Time;
    $SaltedPass md5(sha1($Pass $Salt) . $Salt);
    mysql_query("INSERT INTO users SET
        username='
    $Username',
        pass='
    $SaltedPass',
        salt='
    $Time'"); 
    Kayzio - We don't hesitate, we accelerate.

  20. #20
    SitePoint Addict
    Join Date
    Jan 2006
    Posts
    268
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    edit: you added code to your post :-D


    Thanks for the clarification on salts, kromey. I suppose I was thinking more along the lines of encryption keys..?
    If you give someone a program,
    you will frustrate them for a day;
    if you teach them how to program,
    you will frustrate them for a lifetime.

  21. #21
    Worship the Krome kromey's Avatar
    Join Date
    Sep 2006
    Location
    Fairbanks, AK
    Posts
    1,621
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Kayzio, let me tell you why this is completely unnecessary:

    MD5 produces a 128-bit hash. That is, run some data through it and you will get one of the possible 2^128 (that's roughly 3.40 x 10^38) results. With the now-well-known collision attacks on MD5, this complexity has been reduced to roughly 2^78 (3.02 x 10^23). What that means is that it takes over 300 billion billion (that's not a typo: 300 billion billion) operations to find a word that hashes to the same result.

    To further weaken MD5, there are "rainbow tables" that are essentially lists of MD5 hashes along with strings that produce those hashes. These enable someone to take any MD5 hash and find a string that will produce it.

    Salting is designed to thwart that second type of attack. Even known (you could put your salt in a giant neon sign if you wanted, it doesn't matter), using a salt guarantees that an attacker cannot simply use a rainbow attack to get your users' passwords. (In fact, in every cryptanalysis of salted hashes, one of the basic assumptions is that the salt is always known.) This means that the attacker has to regenerate those 300 billion billion possible results to get your salted passwords. And if you use unique salts for each user, that means 300 billion billion per user account!!

    I suppose the heart of your question is the best method to keep your users' passwords secure should the worst happen, that is, should some Bad Guy(R) break into your server and gain full access to your filesystem. That's simple: use a unique, random, per-user salt; don't use MD5. Generate your salts in whatever manner you wish (I recommend a string of at least 10 characters consisting of upper- and lower-case letters, numbers, and symbols (at the very least those above the numbers on your keyboard)). Then use SHA-256 or SHA-512 (see PHP's hash function). Don't bother with double-hashing unless you really want to (it adds computational time to your application, and although that may not be a concern, there isn't any cryptanalysis to say that you're getting anything in return (which isn't to say that you aren't, just that it's not known if you are or not)). Don't bother with some "secret salt" in addition to your per-user salt: what happens if for whatever reason you lose your script and have no backups? Or you accidentally delete that line and overwrite your backup before you realize the mistake? So long as you store the salt with the user's hashed password and can remember what algorithm you used to generate the hash (that is, what hashing algorithm you used, and whether the salt was prepended or appended), you can always recover from some snafu that would leave all your users locked out with a "secret salt" method.
    PHP questions? RTFM
    MySQL questions? RTFM

  22. #22
    SitePoint Wizard cranial-bore's Avatar
    Join Date
    Jan 2002
    Location
    Australia
    Posts
    2,634
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Off Topic:


    Off the top of my head, there is [url=http://php.net/mcrypt]mcrypt[/php]
    Instead of typing the full url you can just use [ fphp ]mycrypt[/ fphp] and let the forum figure it out for you


    Good thread, Kromey your information has been valuable. I'd always assumed salts should be secret because I'd never really stopped to think about it before.

  23. #23
    SitePoint Wizard bronze trophy devbanana's Avatar
    Join Date
    Apr 2006
    Location
    Pennsylvania
    Posts
    1,736
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I see nothing wrong with storing the salt in the table; in fact i'd recommend it.

    Here's how I generate my salt:

    PHP Code:
      public function generateSalt()
      {
        
    $salt convert_uuencode(
        
    pack(
        
    'H*',
        
    hash_hmac('sha512'uniqid(mt_rand(), true), uniqid(mt_rand(), true))
        )
        );
        
    $this->setSalt($salt);
        return 
    $salt;
      } 
    And my password hashing:

    PHP Code:
      public function setPlainPassword($password)
      {
        
    $password TPropertyValue::ensureString($password);
        
    $salt $this->getSalt();
        
    $this->_password hash_hmac('sha512'$salt $password $salt$salt) . $salt;
      } 
    Laudetur Iesus Christus!
    Christ's Little Flock
    Jesus is the Good Shepherd

  24. #24
    SitePoint Zealot
    Join Date
    Mar 2007
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Very nice post kromey and I think you have cleared everything up for me.
    Kayzio - We don't hesitate, we accelerate.

  25. #25
    <?php while(!sleep()){code();} G.Schuster's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just to throw one thought into your discussion - what about generating the salt based on username and password?
    This would be relatively unique to each user, reconstructable on login and not stored in any way.

    If you have the wrong password the salt is wrong -> authentication against the saved hash fails.
    If you have access to database/filesystem -> nothing happens, you can't "dehash" (ok, wrong term, just for simplification) the hashes due to the missing salt and to generate the salt you would have to know the password.

    Would be nice to read your comments on this.


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
  •