Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

What is/are currently the most cryptographically secure hashing algorithm(s)? (available in PHP)

Speed is irrelevant, because I'm iterating the hash over a fixed time (rather than a fixed number of iterations). What I'm interested in is the mathematical strength.

My intuition tells me it's whirlpool, being the largest and slowest of the bunch. That or SHA-512. But where on the 'net can I see what the experts recommend?

share|improve this question
5  
How can you guarantee that the fixed time always leads to the same number of iterations from run to run? –  Amber Jun 25 '11 at 17:29
1  
By securest do you mean having the largest complexity? Sometimes an algorithm that can be considered strong have other flaws. –  Yet Another Geek Jun 25 '11 at 17:29
3  
No, cryptographic hash algorithms are designed to be one-way functions that make it difficult for an attacker to modify a piece of data while keeping the hash value the same. The one-way function is designed to make it difficult to determine how a change in input will impact the output hash value. Fundamentally cryptographic hashes are lossy compression functions. The information loss in compression makes it difficult to recover the input data. Design specs for MD5, SHA1, Whirlwind, etc, do not mention confidentiality, because is not a design goal. –  this.josh Jun 27 '11 at 7:31
2  
I think the answers here are a little confus(ed|ing) because the time taken by a hashing algorithm is an upper bound on its security. So, except for broken or reduced algorithms, and adjusting for digest length; all hashing algorithms are of equal security if you're iterating for the same amount of time (and doing that in a way that introduces no new vulnerabilities). Except maybe scrypt, since it's memory-hard. –  user502 Jun 27 '11 at 14:07
2  
@Core Why is adjusting manually not an option? Having security depend on server load seems like a bad idea. –  Nick Johnson Jun 28 '11 at 1:29
show 11 more comments

migrated from stackoverflow.com Jun 25 '11 at 18:06

This question came from our site for professional and enthusiast programmers.

5 Answers

Crypographers could point out that, when you read the fine print, there is no proof that secure hash functions actually exist at all. The only thing we have now are candidates for which no weakness has been found yet.

So the best you can hope for is a function which has survived scrutiny by many cryptographers for a long time. Also, you need it to have a wide enough output (256 bits are enough if you wish to achieve "128-bit security" and getting beyond that has little sense). Right now, as of summer 2011, this points to SHA-256 or SHA-512, not Whirlpool.

Basing the iteration count on the time it takes on a typical machine is a good idea -- but basing it on the time it really takes on your machine is not a good idea. Otherwise, you could end up with low iteration counts for some passwords because the machine was handling many requests at that instant (a situation which an attacker could force, by the way). Using many iterations is meant to thwart attackers by making password hashing slow on the attacker's computer -- that it also makes it slow on your system is an unfortunate byproduct; but the true target is whatever machine power the attacker could muster. Since you cannot really make benchmarks on the attacker's machine, you have to resort to rough estimates, hence a fixed count, as high as possible as long as the average burden is tolerable on your system (the important word here being "average", which disqualifies a dynamic measure as you intend to perform).

Also, the attacker's machine needs not look like yours; it may be, e.g., a GPU or a FPGA, which offers distinct computing abilities from what you can get on a typical server. You want a function for which an attacker will not be able to get huge performance boosts by using non-PC hardware. There again, this promotes SHA-256 or SHA-512, which are meant for CPU efficiency (with 32-bit or 64-bit arithmetic operations), not Whirlpool, which can benefit from hardware optimizations similar to those AES was designed for.

Finally, iterations are just part of the job; you also need a long enough, unique enough salt. Iterations and salting can be a bit tricky to do at the same time; you are warmly encouraged to use a standard construction such as PBKDF2 (although it was meant as a key derivation function, not a password hasher, PBKDF2 turns out to be reasonably good at that too).

share|improve this answer
    
All of your concerns had already been addressed in my implementation. The only thing left to figure out is the hash algorithm to use. –  Core Xii Jul 8 '11 at 16:36
add comment

From OP's comment:

"Secure" as in, based on a mathematical problem that has no known fast solution. "Most secure" as in, based on the most complex of such problems. A hashing algorithm is considered "strong" when breaking it would require a major contribution to cryptology/mathematics.

It sounds as if you have been reading Thomas Ptacek's "Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes", and now you're wondering which modern cryptographic hash optimized for password storage is considered 'the most secure'.

I don't think there is a clear-cut answer. As far as I know, some of the current favorites in the programming community (scrypt & bcrypt) haven't been rigorously peer reviewed as password hashing functions. At least, they have not been peer reviewed by a large number of cryptographers comparable to how the NIST hash function competition entries are vetted.

That said, the current Hacker News consensus is that the order is:

  1. scrypt. Because it is both memory-intensive and CPU-intensive, scrypt is thought to have the highest safety margin of current password hashes. You can see more about its design here.
  2. bcrypt was the previous champion, as mentioned in Thomas Ptacek's blog post above.
  3. PBKDF2 and multiple rounds of SHA2 (fx Unix Crypt with SHA256) are thought to be third-best (which one of these is 'best' depends largely on the number of iterations used).

(Note that "Hacker News" is mostly a programming community, and not as the name might imply to some a security specialist community (even though some of those hang out there too).)

If you look around on this site, under the cryptography passwords and hashing tags fx, then you will see that there usually isn't a single 'best' password hash mentioned. I guess that's in part because the real cryptographers have no clear-cut consensus on which one is 'strongest', due to the relatively limited peer reviewing.

Here is a fairly even-handed and easily read comparison (which doesn't include scrypt, presumably because it's still too new).

Speed is irrelevant, because I'm iterating the hash over a fixed time (rather than a fixed number of iterations).

With some of these hashes, you can't really do that. You supply a "work factor" when you call the library, and the library takes care of the rest.

share|improve this answer
    
scrypt is not available for PHP. bcrypt and PBKDF2 implement the adjustable cost as an iteration count, and requires fine-tuning for each point in time. I've already solved that by adjusting the cost by time rather than a flat count. Now I'm just wondering what hashing algorithm to use. –  Core Xii Jun 27 '11 at 6:54
4  
@Core Xii: You seem bent on implementing your own novel solutions -- it is axiomatic that one shouldn't do that, "Don't roll your own crypto". In your case, I would suggest using PHP > 5.3.2 and use PHP's crypt() with Blowfish and default values (aka bcrypt). php.net/manual/en/function.crypt.php You can see the format description here (not PHP, but same format AFAIK) packages.python.org/passlib/lib/… –  Jesper Mortensen Jun 27 '11 at 10:12
    
I can not fine-tune the cost parameter manually, that is out of the question. And there exist no implementations with dynamic adjustment, so I'm forced to roll my own. I did not ask what tool I should use to crypt my passwords, I asked for the most secure hashing algorithm. Blowfish is not a hashing algorithm. –  Core Xii Jun 27 '11 at 12:36
3  
@Core Xii: While "Blowfish" isn't a hashing algorithmn, there is a password hashing algorithm that is called "CRYPT_BLOWFISH" in some circles. That's already covered in @Allan Jude answer and in my links above. You seem to want to create your own password hashing scheme; and I'm not able to assist you further in doing so. –  Jesper Mortensen Jun 27 '11 at 14:21
1  
You could implement "pick #iters based on time taken" using a library-provided bcrypt -- just time the bcrypt call and if it's "too quick" increase the workload factor and re-try. But are you sure you want that? What if someone deploys your code onto a slow machine (e.g. a small VM) -- you don't want to get too-small work factors as a result. What if your system is left on a "2011" spec machine through to 2019 when all the attackers have 128-way 20GHz boxes? What if the attacker can use a DoS to increase the time your hashing takes? You will at least want a secure-for-now initial work factor. –  Misha Sep 12 '11 at 12:15
add comment

CRYPT_BLOWFISH (OpenBSD bcrypt, based on the blowfish symmetric cipher, but is an actual hashing algorithm, there seems to be a lot of confusion about this) and CRYPT_SHA512 are the best. Both of these provide the option to scale the number of 'rounds' used, allowing you to choose a security/performance tradeoff.

For example, the default number of rounds for blowfish is 7 (value range is 4-31). This value is logarithmic, so each increase results in the algorithm being run 10 times more. A value of 13, takes almost 1 minute per hash on a Core2Duo 2.4ghz

Tuning this as high as is tolerable performance wise, will result in the strongest security.

note: recently a bug was found in some implementations of bcrypt, and as such, you may wish to use SHA-512 instead.

Note: SHA-512 is faster to compute than SHA-256 on 64bit processors (especially if optimized w/ SSE2_64. Specifically, you should consider this and use additional rounds to ensure your hashes are strong enough for their purpose.

The open source application hashkill, publishes some performance benchmarks on how quickly modern GPUs can crack through modern hashing algorithms. Specifically, a Radeon HD 6990 can do: 11001 Megahashes/sec of straight MD5 (CRYPT_MD5 is salted, and the FreeBSD implementation uses 100 rounds). Straight SHA1 at 3444 Megahashes/s.

share|improve this answer
    
Once again, I don't want to tune the tradeoff; Hence I wrote a system that iterates automatically by time, thus remaining constant in its security over time. Now I'm just looking for the most secure hashing algorithm to use with it. The benchmark only compares MD5 and SHA-1 (both of which are broken), and so is completely useless. –  Core Xii Jun 27 '11 at 7:00
add comment

I recommend you to use phpass

This is a portable public domain password hashing framework for use in PHP applications. It is meant to work with PHP 3 and above, and it has actually been tested with at least PHP 3.0.18 through 5.3.0 so far.

The preferred (most secure) hashing method supported by phpass is the OpenBSD-style Blowfish-based bcrypt, also supported with our public domain crypt_blowfish package (for C applications), and known in PHP as CRYPT_BLOWFISH, with a fallback to BSDI-style extended DES-based hashes, known in PHP as CRYPT_EXT_DES, and a last resort fallback to MD5-based salted and variable iteration count password hashes implemented in phpass itself (also referred to as portable hashes).

Like the website says Blowfish-based bcrypt is the most secure hashing. I believe this is true because it is "Moore's law proof" while most others are not.

share|improve this answer
    
It uses MD5 (a no-no). Also, read my question again. My system is Moore's law proof automatically, whereas PHPass requires manual fine-tuning of the iteration count for each point in time. –  Core Xii Jun 27 '11 at 6:56
    
@Core Xii, it can use md5, for backward compatibility. But it does not by default and can be configured to only use BCrypt. –  Jacco Jun 27 '11 at 12:32
    
@Jacco: I'm looking at the source right now and there's a clear comment: "We're kind of forced to use MD5 here since it's the only cryptographic primitive available in all versions of PHP currently in use." –  Core Xii Jun 27 '11 at 12:42
    
I know the source, if you set 'portable hashes' to false, it will not use md5. –  Jacco Jun 27 '11 at 12:50
    
@Jacco: The execution path for CheckPassword() always goes through crypt_private() which always uses MD5. –  Core Xii Jun 28 '11 at 10:53
show 1 more comment

According to my personal experience, I consider Blowfish as one of the most secure encryption algorithm

Click Here to download the pdf documentation on Blowfish.

It is a symmetric block cipher that can be used as a drop-in replacement for DES or IDEA. It takes a variable-length key, from 32 bits to 448 bits, making it ideal for both domestic and exportable use. Apart from that, Blowfish is unpatented and license-free, and is available free for all uses.

share|improve this answer
    
Blowfish is a hash algorithm? –  Dee Jay Jun 25 '11 at 17:51
    
Blowfish is absolutely not a hash algorithm, and using it as if it were one will lead to tears. –  duskwuff Jun 25 '11 at 17:53
2  
Blowfish is not a hashing algorithm, though. I don't know how exactly bcrypt uses Blowfish but generally encryption is a completely different thing from hashing. –  Core Xii Jun 25 '11 at 17:55
1  
If blowfish is not a hash algorithm, then I think people should make it clear and downvote it accordingly. –  user774411 Jun 25 '11 at 18:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.