webdevRefinery Forum: Best Hashing Algo for Storing Passwords? - webdevRefinery Forum

Jump to content

  • 2 Pages +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

Rate Topic: -----

User is offline TheMaster 

  • *-c0de master-*
  • Group: Members
  • Posts: 748
  • Joined: 24-May 10
  • LocationAustralia
  • Expertise:HTML,CSS,PHP,Java

Posted 21 April 2012 - 10:09 PM (#1)

Best Hashing Algo for Storing Passwords?


I'm used to using SHA1 for storing passwords (with a random salt added of course), but I was talking to some people about it, and they said that SHA1 (and MD5) are not good algo's for storing passwords due to how quickly they can generate hashes (brute forcing etc.)

I looked on the PHP docs, and apparently they say the same thing there as well. PHP recommended Blowfish, as the best algo for storing passwords.

I was wondering what you guys thought?
0


User is offline NeilHanlon 

  • Group: Members
  • Posts: 884
  • Joined: 08-July 10
  • LocationRowley, Massachusetts
  • Expertise:HTML,CSS,PHP,Java,Graphics

Posted 21 April 2012 - 10:22 PM (#2)

As a general rule, we almost all do the following to encrypt passwords:

md5(md5($pass) . md5($salt));


This is what almost everyone I've looked at does. With the exception of vBulletin, who uses the following:

md5($pass . $salt);

Thanks,
兄ニール

Website | Blog | @NeilHanlon | About.Me | Facebook | LinkedIn
0


User is offline TheEmpty 

  • I say words in sequences.
  • Group: Members
  • Posts: 5154
  • Joined: 02-October 10
  • Expertise:HTML,CSS,PHP,Java,Javascript,Python,Ruby on Rails,SQL

Posted 21 April 2012 - 10:57 PM (#3)

Yes, blowfish, it's amazing. As technology scales, the alg. scales with it (the server hardware that is). You set how many times it encrypts the password, "stretches." You could say it looks something like this:

def blowfish(string, stretches = 5)
  salt = generate_salt
  string += salt
  stretches.times { string = encrypt string }
  return "$#{salt}$#{stretches}$#{string}"
end


Reserved.
0


User is offline DarkCoder 

  • Group: Members
  • Posts: 1463
  • Joined: 08-March 10
  • LocationEngland, United Kingdom
  • Expertise:HTML,CSS,PHP,Javascript,SQL

Posted 22 April 2012 - 04:03 AM (#4)

View PostThatRailsGuy, on 21 April 2012 - 10:57 PM, said:

def blowfish(string, stretches = 5)
  salt = generate_salt
  string += salt
  stretches.times { string = encrypt string }
  return "$#{salt}$#{stretches}$#{string}"
end


Keep your rails out of the PHP section :P
1


User is offline Daniel15 

  • dan.cx
  • Group: Moderators
  • Posts: 3415
  • Joined: 17-April 10
  • LocationMelbourne, Australia
  • Expertise:HTML,CSS,PHP,Java,Javascript,Node.js,SQL

Posted 22 April 2012 - 04:51 AM (#5)

MD5 and SHA1 are fast. This is bad for passwords, as it makes it quicker to brute-force them. As hardware gets faster, cracking passwords gets easier

The recommended algorithms are generally bcrypt or PBKDF2. bcrypt is based on Blowfish, and adapts to hardware (as hardware gets faster, the algorithm takes longer to execute). I believe PHP's
crypt
function supports it. I quickly Googled and found https://gist.github.com/1053158 which looks okay.

Some great references on StackExchange:
http://security.stac...assword-storage
http://security.stac...re-secure?atw=1
Daniel15! :D
Posted Image

Repeat after me: jQuery is not JavaScript. It is not the answer to every JavaScript-related question. When you have to write some JavaScript, do not instantly react with "Oh, I'll do that with jQuery!"

Spoiler
1


User is offline TheEmpty 

  • I say words in sequences.
  • Group: Members
  • Posts: 5154
  • Joined: 02-October 10
  • Expertise:HTML,CSS,PHP,Java,Javascript,Python,Ruby on Rails,SQL

Posted 22 April 2012 - 09:35 AM (#6)

View Postolie122333, on 22 April 2012 - 04:03 AM, said:

Keep your rails out of the PHP section :P

I forgot how to write pesedu code and didn't feel like writing Java, been about a month since I've written Ruby q.q
Reserved.
0


User is offline callumacrae 

  • {{ post.author }}
  • Group: Members
  • Posts: 2862
  • Joined: 20-January 11
  • LocationWarwickshire, England
  • Expertise:HTML,CSS,PHP,Javascript,Node.js,SQL

Posted 22 April 2012 - 09:52 AM (#7)

View PostThatRailsGuy, on 22 April 2012 - 09:35 AM, said:

pesedu code

lol
Front-end developer and writer
Twitter | GitHub | phpBB Contributor and Website Team Member | lynxphp
0


User is offline TheEmpty 

  • I say words in sequences.
  • Group: Members
  • Posts: 5154
  • Joined: 02-October 10
  • Expertise:HTML,CSS,PHP,Java,Javascript,Python,Ruby on Rails,SQL

Posted 22 April 2012 - 11:00 AM (#8)

View Postcallumacrae, on 22 April 2012 - 09:52 AM, said:

lol

autocorrect, was on iPod.
Reserved.
0


User is offline TheMaster 

  • *-c0de master-*
  • Group: Members
  • Posts: 748
  • Joined: 24-May 10
  • LocationAustralia
  • Expertise:HTML,CSS,PHP,Java

Posted 22 April 2012 - 07:31 PM (#9)

View PostThatRailsGuy, on 22 April 2012 - 11:00 AM, said:

autocorrect, was on iPod.


It is even possible to blame auto-correct for spelling something thats not even a word? :P
0


User is offline Vakz 

  • Group: Members
  • Posts: 2
  • Joined: 07-May 12

Posted 07 May 2012 - 04:23 AM (#10)

Isn't encrypting generally bad advice for storing password? Personally, I've always preferred hashing, since there's rarely any reason you'd want to unencrypt a password; better to just generate a new one, since this would also stop anyone who has gained access to a user's email from getting the password. Sure, the user probably has an account with the same email at a less secure site, but at least you're not the weak link :)

For hashing, SHA512 is generally a good enough algorithm. Throw in a long salt (I usually go for 60+ characters) and hash it some 20,000 times, and it's Really unlikely that someone will manage to bruteforce any password, should they manage to dump your database.
0


User is offline callumacrae 

  • {{ post.author }}
  • Group: Members
  • Posts: 2862
  • Joined: 20-January 11
  • LocationWarwickshire, England
  • Expertise:HTML,CSS,PHP,Javascript,Node.js,SQL

Posted 07 May 2012 - 05:26 AM (#11)

View PostVakz, on 07 May 2012 - 04:23 AM, said:

Isn't encrypting generally bad advice for storing password? Personally, I've always preferred hashing, since there's rarely any reason you'd want to unencrypt a password; better to just generate a new one, since this would also stop anyone who has gained access to a user's email from getting the password. Sure, the user probably has an account with the same email at a less secure site, but at least you're not the weak link :)


There is *never* any reason to unencrypt a password!

View PostVakz, on 07 May 2012 - 04:23 AM, said:

For hashing, SHA512 is generally a good enough algorithm. Throw in a long salt (I usually go for 60+ characters) and hash it some 20,000 times, and it's Really unlikely that someone will manage to bruteforce any password, should they manage to dump your database.

Overkill muchly! Even md5 is still fine for most applications, if used correctly.
Front-end developer and writer
Twitter | GitHub | phpBB Contributor and Website Team Member | lynxphp
0


User is offline Sephern 

  • Group: Moderators
  • Posts: 967
  • Joined: 04-June 10
  • LocationReading, UK
  • Expertise:HTML,CSS,PHP,Javascript,Python

Posted 07 May 2012 - 08:04 AM (#12)

Hashing it multiple times can actually reduce the entropy.

BCrypt is the generally recommended solution now I believe. As Daniel said, MD5 is quick, which means that anybody with a bit of free time and some money to throw at parallel computers (like CUDA clusters) can crack your passwords. BCrypt stops that by having a 'work factor' which makes it slower to calculate. Half a second probably doesn't matter to somebody logging in, but when you're trying to crack 500,000 passwords then adding half a second to each of them makes it quite considerably longer.

Naturally, its unlikely somebody will go to that level of effort to crack your passwords, but for the sake of changing one function call there's no real reason not to.
0


User is offline Vakz 

  • Group: Members
  • Posts: 2
  • Joined: 07-May 12

Posted 07 May 2012 - 10:12 AM (#13)

View PostSephern, on 07 May 2012 - 08:04 AM, said:

Hashing it multiple times can actually reduce the entropy.


I have never that before. Any chance you could clarify, or link me in the right direction? :)
0


User is offline Sephern 

  • Group: Moderators
  • Posts: 967
  • Joined: 04-June 10
  • LocationReading, UK
  • Expertise:HTML,CSS,PHP,Javascript,Python

Posted 07 May 2012 - 11:33 AM (#14)

View PostVakz, on 07 May 2012 - 10:12 AM, said:

I have never that before. Any chance you could clarify, or link me in the right direction? :)

Well, the simple way of looking at it is that every hashing function has a limited entropy. It can only return a finite number of values. In the case of MD5 for example, this is 2^128. When you encrypt a password multiple times all you're doing is feeding in one hash and getting another one back. Its not getting any more secure or 'more random' every time. It can still (presumably) collide though, so depending on the algorithm the entropy could reduce (although admittedly it doesn't seem likely).

The only possible security benefit that you'll get from that is that it takes longer to calculate. Which is a perfectly admirable goal. In fact, thats the primary problem with most hashing methods today. The actual hash itself isn't any more secure though, and in a relatively short amount of time the 20,000 hashes or whatever else you're doing isn't going to mean anything to anybody with a relatively decent computer.

By using things like bcrypt you're using an algorithm which is designed to be slow rather than fast, regardless of hardware or technology. Why invent it yourself when you have algorithms which build in the concept of a work factor to make it slower? Amongst other things you're pretty much guarenteed that it will always be implemented more correctly than any security solution you do yourself.

Like I said before, providing you're not storing passwords in plaintext, or without a salt, or making your own algorithm, or a ton of other basic security fails then you should be fine. The general 'best practice' though would be to use BCrypt or similar - Algorithms designed especially for the purpose (which md5 and sha are not).
1


User is offline Daniel15 

  • dan.cx
  • Group: Moderators
  • Posts: 3415
  • Joined: 17-April 10
  • LocationMelbourne, Australia
  • Expertise:HTML,CSS,PHP,Java,Javascript,Node.js,SQL

Posted 07 May 2012 - 06:07 PM (#15)

Quote

For hashing, SHA512 is generally a good enough algorithm. Throw in a long salt (I usually go for 60+ characters) and hash it some 20,000 times,

Quote

Hashing it multiple times can actually reduce the entropy.

If the algorithm could be made more secure by running it multiple times, it'd already be doing that. Hashing multiple times does not increase security for algorithms like SHA1 and MD5. That's exactly what bcrypt and PBKDF2 do, though. It's a feature of those algorithms, implemented in a secure way.

One approach I've seen for storing passwords is to have both a hashed password column and a "algorithm" column specifying the name of the hashing algorithm. This means you know which algorithm each password is hashed with, and can migrate users over to a new algorithm when they log in (check if their password uses the old algorithm, and if so, re-hash it and save it with the new algorithm).

In the end, though, OpenID and OAuth should win so you never need to deal with passwords again. http://stuff.dan.cx/php/login/
Daniel15! :D
Posted Image

Repeat after me: jQuery is not JavaScript. It is not the answer to every JavaScript-related question. When you have to write some JavaScript, do not instantly react with "Oh, I'll do that with jQuery!"

Spoiler
1


User is offline Sephern 

  • Group: Moderators
  • Posts: 967
  • Joined: 04-June 10
  • LocationReading, UK
  • Expertise:HTML,CSS,PHP,Javascript,Python

Posted 08 May 2012 - 11:17 AM (#16)

View PostDaniel15, on 07 May 2012 - 06:07 PM, said:

One approach I've seen for storing passwords is to have both a hashed password column and a "algorithm" column specifying the name of the hashing algorithm. This means you know which algorithm each password is hashed with, and can migrate users over to a new algorithm when they log in (check if their password uses the old algorithm, and if so, re-hash it and save it with the new algorithm).

This is the approach used by Django.

I'm not too convinced that online-passport like systems are good. There's the issue of user experience (for example, OpenID is horrific), and issues with being signed on to multiple sites (if I log out of 1 does it log me out of everything? Again, there's a bit of work to be done on the user interaction side). There's also the issue that people don't know about these systems unless they're geeks. Nobody really recognises OpenID/OpenAuth that much.

Facebook, Google, MS Passport etc are probably better solutions because people instantly recognise them (and know if they have a Facebook account, for example). The entire experience is a lot more familiar. With a lot of these systems they're informed exactly what data the website wants to have about that user (so you aren't giving random sites access to your personal information). In general they seem a lot more 'smooth'. Some of the standard idioms still don't exist here (though some of them are obviously going to change, not all of them should), so there's still a bit of work to be done. There's also the issue of 'personas' associated with logging in with social networks (for example, if I am part of an online gaming forum I might not want people to find my facebook).
0


User is offline TheMaster 

  • *-c0de master-*
  • Group: Members
  • Posts: 748
  • Joined: 24-May 10
  • LocationAustralia
  • Expertise:HTML,CSS,PHP,Java

Posted 21 May 2012 - 01:36 AM (#17)

Just going back to the hashing thing for a bit, why exactly, does hashing a password multiple times NOT increase entropy?

This is show I see it. Please correct me where I'm wrong. I'll use "P" to mean password, and "H" to mean hash.

P -> hashed -> H1 -> hashed -> H2 -> hashed -> H3

Now, if somebody were to brute force H3 using rainbow tables, or any other method, they will result in a match, of H2. They then need to crack that, resulting in H1, and then crack that, resulting in the password.

This triples the time taken from initial hash to final result (password), meaning the entropy (or complexity, or whatever) from password -> hash, is also increased.

Is that right, or am I completely wrong?
0


User is offline Daniel15 

  • dan.cx
  • Group: Moderators
  • Posts: 3415
  • Joined: 17-April 10
  • LocationMelbourne, Australia
  • Expertise:HTML,CSS,PHP,Java,Javascript,Node.js,SQL

Posted 21 May 2012 - 05:56 PM (#18)

Quote

Is that right, or am I completely wrong?

You're more likely to encounter hash collisions if you hash more than once.

And hashing three times is way too little - You can calculate millions of MD5 hashes per second on fast equipment. Modern hashing algorithms use 50,000 or 100,000 iterations (or more).

Read through some of the comments at http://security.stac...hash-passwords. This one is pretty good.

In the end, if it was more secure for the algorithm to be ran multiple times, it'd already be doing that. Nobody writes a "half secure but could be improved" algorithm :P
Daniel15! :D
Posted Image

Repeat after me: jQuery is not JavaScript. It is not the answer to every JavaScript-related question. When you have to write some JavaScript, do not instantly react with "Oh, I'll do that with jQuery!"

Spoiler
1


User is offline TheMaster 

  • *-c0de master-*
  • Group: Members
  • Posts: 748
  • Joined: 24-May 10
  • LocationAustralia
  • Expertise:HTML,CSS,PHP,Java

Posted 22 May 2012 - 01:03 AM (#19)

Ok....but.....from the perspective of somebody trying to crack the hash, wouldn't hashing it 100,000 times be more secure than once? Simply because you'd need to "work down the chain" of hashes, until you reached the original (the password), or is that not how hashes work?
0


User is offline ianonavy 

  • Group: Members
  • Posts: 685
  • Joined: 14-April 10
  • Expertise:HTML,CSS,Java,Javascript,Python

Posted 22 May 2012 - 08:56 AM (#20)

View PostTheMaster, on 22 May 2012 - 01:03 AM, said:

wouldn't hashing it 100,000 times be more secure than once?

No, it would just take a marginally longer time to calculate the password. Common hash functions like SHA1 and MD5 are ridiculously fast for any modern computer to calculate. Security comes not from how long it takes for someone to brute force a password, but rather how unlikely it would be that they would randomly guess it. If you feed a hash back into a hash, you still get another hash of the same length with the same amount of entropy. Hash functions work by taking any size input and turning it into a very very highly likely unique set of bits with a fixed length (usually 128 or 160 depending on the algorithm). However, because the number of hashes an algorithm can produce is finite, it is mathematically possible (but extremely unlikely) for two passwords to produce the same hash. By running the hash algorithm multiple times, you effectively reduce the number of "possible hashes" that the algorithm can use for hashes, and that makes collisions exponentially more likely, which is bad bad BAD for password hashing.

View PostDaniel15, on 21 May 2012 - 05:56 PM, said:

In the end, if it were more secure for the algorithm to be ran multiple times, it'd already be doing that.

This. SHA1 and MD5 are secure because of the immense amount of possible hashes they can produce. By running them multiple times, you're reducing their security (by slightly decreasing the entropy) in exchange for a few more microseconds of calculation.


Let me illustrate this with an example. Let's say that a password-obfuscating algorithm does this by counting the number of vowels, then the number of consonants and storing it as a concatenated string and fitting a bunch of zeros to make it a fixed-length. "Iamyourcatoverlord" corresponds to "00000710". Now a computer that wants to reverse this algorithm is going to have a difficult time because the output string "00000710" could be interpreted as 71 vowels, 0 consonants OR 7 vowels and 10 consonants. For each situation, they have to iterate through the 21 possible consonants and 5 possible vowels (I did not count y in this case). This algorithm's security comes from making it difficult to guess a password that would produce the same hash that the original password produces.

What a cracker could do, however, is reverse the algorithm and try every possible combination of letters and vowels that fit with either 71 vowels, 0 consonants or 7 vowels and 10 consonants. Considering you can get any computer that can calculate 10 GigaFLOPS (that is, 10 billion floating-point operations in a second) for relatively cheap, any password protected by this algorithm would be guessed practically instantly. The major drawback is that passwords like "cat" and "dog" produce the same hash: "00000021". That means that a cracker can guess the word "dog", even though the user normally enters "cat", and the server will hash both passwords to mean the same "0000021", and "dog" will give the cracker access.

MD5, which is often mistaken to be insecure for passwords, produces a 128-bit hash value. That means that there are 2^128 or 3.40 × 10^38 possible hashes that can be produced by MD5. At an average speed of 10 GFLOPS, a desktop PC would take 3.40 × 10^28 seconds or 1.08 × 10^21 years to go through every possible hash! Now that's an average desktop PC. More than likely, your cracker will be using some sort of distributed system to achieve more FLOPS, or much more powerful hardware. It's still going to take them a long time, especially if you salt the password first. Every time you run MD5 more than once, you reduce the number of possible hashes that can be produced while only marginally increasing how long it takes for the computer to calculate it. Considering that MD5 takes only around 624 operations to calculate, you'd have to run it 16,025,641 times to make it take a second longer for a cracker to calculate a password for a hash, while giving them exponentially more passwords that could possibly produce the same stored hash value. This is why running secure hash algorithms more than once is generally frowned upon by security experts.

Edit: I can spell "overlord".
reputation += 1 if post.is_helpful else 0
5


Share this topic:


  • 2 Pages +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

2 User(s) are reading this topic
0 members, 2 guests, 0 anonymous users


Enter your sign in name and password


Sign in options
  Or sign in with these services