17

Which is the best recommended algorithm to use for encrypting passwords in php/mysql

Gatura
  • 605
  • 2
  • 8
  • 15

7 Answers7

21

SHA-512 with a salt is a good & secure way to hash a password. If that's not available you have SHA-1 but it's security is considered a bit weak these days, especially if you don't use a salt.

TravisO
  • 9,406
  • 4
  • 36
  • 44
  • Are you saying SHA-512 is worse or less secure? – Core Xii Oct 18 '10 at 18:44
  • 2
    Well obviously SHA-512 is even stronger, now you're just being a smart arse. – TravisO Nov 04 '10 at 19:10
  • 1
    I would not agree. Read this article: http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html – miki725 Jan 10 '11 at 02:47
  • 3
    +1, Salt SHA-512 is the best option. – Johan Oct 07 '11 at 11:53
  • 2
    -1 This answer is hopelessly out-of-date. Use PBKDF2, bcrypt or scrypt. – luiscubal Jul 22 '13 at 21:34
  • 2
    You negative vote a 3 year old post bet you feel smart now... Look at the dates. Someone can post 6 months back from today the best hashing method and it would then turn to be worse then the new methods today. Its common sense codes chance rapidly! – EasyBB Jun 19 '14 at 03:29
  • 1
    Yes your comment is a year old yet I feel like I want to smack you for down voting a 3 year old answer. – EasyBB Jun 19 '14 at 03:30
  • SHA-512 is a FAST algorithm, meaning someone who obtains the hash can brute-force it very quickly, especially with dedicated hardware. You need an algorithm that can increase its "rounds" or "cost" as time goes by to increase the actual financial cost to the person trying to brute-force the hash. – Kevin Nelson Dec 18 '14 at 18:44
  • @MichailMichailidis of course, the answer is 5 1/2 years and counting – TravisO Jul 07 '15 at 20:23
  • @TravisO consider removing it then – Michail Michailidis Jul 08 '15 at 14:00
  • @MichailMichailidis are you seriously expecting people to modify, update, remove every single comment or answer they've ever made on this site over the past ~7yrs? – TravisO Jul 16 '15 at 20:41
  • @TravisO When it is a matter of security yes! you can still edit your answer to prevent people learning really risky things – Michail Michailidis Jul 16 '15 at 21:11
  • @MichailMichailidis write a better answer yourself or add a comment to said answer on that old post. Harassing people about old answers is a fruitless endeavour. "It's old" helps nobody, not the original author, not future viewers of this post, nor me. Has it ever occurred to you maybe I don't even know a better solution. – TravisO Jul 17 '15 at 12:35
  • @TravisO Obviously algorithms like bcrypt / arbitrarily configurable slow algorithms that have the salt in them are the way to go. luiscubal commented that 2 years ago.. you could edit your answer saying "fyi this answer is no longer relevant to what is considered secure".. I am not going to edit your post if you think that my comment was a harassment... – Michail Michailidis Jul 17 '15 at 20:35
8

Most people now agree SHA is not the best way to go, since these algorithms are bad at resisting brute-force attacks. It's better to use bcrypt, scrypt or PBKDF2 see this Q&A.

Here is a guide on how to implement bcrypt in php.

Community
  • 1
  • 1
eldh
  • 336
  • 2
  • 8
6
  1. Current thinking is to use a SLOW hash algo. This causes "brute forcers" to spend lots of time generating all those attempts.

  2. Much smarter still is to track URI requests by IP and block with explanation when 5 login attempts fail from same IP within any given 5 minute period.

  3. Bank-smarter still is to do #1, #2 and also require a secondary pass challenge once the first one succeeds. Triple failure at second challenge results in lock-out.

Level 3 security is very, very strong. Probably too strong.

FYA
  • 402
  • 4
  • 6
  • One clarification to what you wrote. You make it sound like #2 is "better" than #1...but they are completely independent and both are needed. You don't hash to prevent brute-force attacks against your server. That type of brute-force attack never "sees" the hash. So, for that, you do item #2 only. You hash your passwords to prevent people who have access to the DB or get a dump of it from being able to inexpensively brute-force your users passwords at their own leisure. – Kevin Nelson Dec 18 '14 at 19:00
4

There's a decent article here - short answer, use crypt(), and make sure you use a salt.

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
1

Miki725 raises interesting points with the Matasano article Whilst sha512 is better than md5 cryptographically, bcrypt beats them all because it is slower and thus costs more to attack. Slower is not bad the internet is slow already, it's millions of times slower than CPU cache, and thousands of times slower than disk. Making password checks take 200ms instead of 1ms to compute is not going to bother any users.

Most importantly do not forget to use a nonce that is randomly generated and different for each user.

bcrypt is going to be sub-optimal in PHP because php is interpreted and this gives the attacker some advantage but there's a how to in this stackoverflow article

Community
  • 1
  • 1
user340140
  • 628
  • 6
  • 10
1

I would use the php's crypt() function because there will not be anyway for the password to be decrypted. When I need to check the newly entered password I just have to encrypt that one and compare the two results

phunehehe
  • 8,618
  • 7
  • 49
  • 79
  • 14
    -1 complete non-sense: according to the manual: `crypt() will return a hashed string using the standard Unix DES-based algorithm or alternative algorithms that may be available on the system.` – Johan Oct 07 '11 at 11:52
  • 6
    @Johan You can easily change the hash function to be used, salt and the number of rounds with `crypt()`. – Daniel Jonsson Jul 01 '12 at 21:36
  • 1
    @Daniel Jonsson +1 The snippet of documentation that Johan mentions even says so! Rudeness should not be welcome here. – allyourcode Dec 08 '12 at 23:21
  • I'm not sure why crypt got voted down so much while SHA-512 got voted up so high...? crypt can, at the very least, use bcrypt or CRYPT_SHA512 which can specify the number of rounds/cost and make the hashing much more secure. However, you are mistaken in using the words "encrypted" and "decrypted". Hashing is NOT encryption, and no matter how you hash, it CAN be brute-forced...the security of hashing is when you use a lot of processing power, which makes it "expensive" for someone to brute-force the hash. – Kevin Nelson Dec 18 '14 at 18:49
  • Also, if you have PHP >= 5.5, it is now "best" (as in recommended by PHP itself) to use password_hash and password_verify. In particular password_verify is a slow_equals method to prevent timing attacks. – Kevin Nelson Dec 18 '14 at 19:03
0

There are a lot of options - see the php hash docs for the complete list.

Speed is not an advantage, so using sha-512 or whirlpool is a good idea. You don't have to store the full length of the hash in mysql, for instance you could hash something as whirlpool, which is 128 characters long, and store only the first 64 characters for efficiency.

JAL
  • 21,295
  • 1
  • 48
  • 66
  • 1
    Truncating a hash is very bad advice, and is absolutely unnecessary, as sha256 will return 64 hexadecimal digits, and it's designed for that length. Truncating any hash will lower security significantly! Also you are writing about 128 characters - 0-9,a-f. This is inefficient storage of binary values such as hash, as it's taking twice as much space, so 64-bit binary field would store your 128 characters and you don't need to truncate anything. Although it could be better for maintenance to have hash in more readable format, you can use base64 encryption. – marianboda May 13 '10 at 18:30
  • @praksant I'm not a crypto expert, but it seems to me that storing characters 32-96 of a whirlpool hash is good enough for the vast majority of applications. It does increase the chances of an attacker finding a collision, but still, this would be be a lot better than SHA1/MD5, which so many people still use. What improvement would it be to use base64? – JAL May 13 '10 at 22:14
  • 1
    I'm no crypto expert either, but if there is a way to store whole hash in the same number of bytes, why should anyone make a sacrifice in security for nothing? I'm not saying it's not secure enough for many applications. It might be. And base64 encoding will store binary data at 6 bits per byte, hexadecimal form only 4 per byte. So with base64 you would need 86 bytes to store 512-bit hash instead of 128 bytes. In raw binary it would be 64 bytes. – marianboda May 14 '10 at 00:45