3

The winner of SHA-3 hashing algorithm contest has been chosen. The winner's algorithm is Keccak.

I use Blowfish and really like it, but Keccak is said to be better. Is it worth to use it for storing user's passwords on my website?

If yes, are there any implementations of Keccak for PHP, Python, Ruby or any other languages, used in web programming?

I hope this question will help other people, too. Thanks!

TheJSB
  • 151
  • 1
  • 9
  • Once you have a hashing algorithm it gets difficult to switch. You have to maintain both until all passwords are converted. Which might be never. Unless you have a good reason to suspect that your current solution is not secure enough, I wouldn't worry about it. – datasage Feb 08 '13 at 18:48
  • Any point of downvoting? I googled it and searched for similar questions on Stack Overflow. – TheJSB Feb 08 '13 at 18:53
  • You should really use a ready solution like PBKDF2, listen to Eli's answer. Your question seems to assume the hash algorithm is the thing to choose but you really need a whole secure construction. – u0b34a0f6ae Mar 04 '13 at 13:21

3 Answers3

21

short answer:

No, and probably never. For password hashing, BCrypt & PBKDF2-HMAC-xxx are better choices than any simple SHA-1/2/3 algorithm. And until SHA-1/2 actual have feasible preimage attacks published, SHA-3 is actually the worst choice, specifically because of it's speed and low cache footprint.

longer answer:

A major factor in the relative security of different password hashing algorithms is: how much faster can a dedicated attacker hash passwords compared to you? That is, how much faster is their software/hardware combination (purchased for the express purpose of password hashing), versus your software on your server (off-the-shelf C implementation for software, hardware purchased for the needs of your application).

One of the main SHA-3 criteria was that is should run efficiently on embedded architectures, which are typified by small amounts of on-die cache, registers, etc. But this also describes modern GPUs: fewer registers/accumulators, smaller on-die caches; but on the flipside, their silicon is optimized to perform the same task in parallel on LARGE amounts of data. This is perfect for your attacker's brute-force attempts: for ever dollar spent on silicon, your attacker gets more SHA3 hashes/sec by buying another GPU than you do by buying a better CPU.

For this specific reason, BCrypt was designed to do a larger number of reads/writes to an in-memory table, one that's currently larger than the cache of most GPUs. Which means the current GPU-based BCrypt implementations aren't even up to speed with their CPU counterparts. So just by choosing BCrypt, you've slowed down your attacker's advantage for every dollar he spends, by forcing him to buy CPUs the same as you.

This is why raw speed is the enemy of password hashing. You want to choose the algorithm whose fastest software/hardware combination offers your attacker the least advantage per dollar over the commodity software/hardware that you'll be using. Right now, that's BCrypt, or the slightly lesser choice of PBKDF2-HMAC-xxx. Since GPUs are probably only going to getter better at doing SHA3, I doubt it'll ever be the correct choice. I don't have the numbers on SHA3, but "which is more secure" is not a nebulously relative term - the above rule can be used to precisely quantify it.

Eli Collins
  • 8,375
  • 2
  • 34
  • 38
  • This, is a fantastic answer. I hadn't even considered it, but you @Eli_Collins, made it obvious that a slower algorithm is advantageous -- particularly for password hashing. – ChaseMoskal Aug 20 '13 at 00:32
4

This is an old question, but it sounds like everyone is confused by cryptography terminology again. Let's clear a few things up.

  • Keccak is a cryptographic hash function.
  • Blowfish is a block cipher (which has a 64-bit block size and shouldn't be used for encryption anymore).
  • Bcrypt is a password hashing function, which has a different use-case than a mere cryptographic hash function. Bcrypt is based on Blowfish, but it isn't Blowfish.

I'm not just being pedantic; these distinctions are important because Keccak isn't competing with bcrypt, it's competing with SHA-256.

Here's an easy way to safely store a password in PHP:

  1. Use password_hash(), password_verify(), and password_needs_rehash()

That's it. You don't even need to care what these functions do, you just need to use them (unless you're using something like libsodium instead).

Currently, this interface provides bcrypt. Bcrypt is mostly fine, except for a few foot-bullets to watch out for:

  1. It truncates passwords after 72 characters, which degrades the security of long passwords with a low entropy-per-character keyspace.
  2. If you try to circumvent the previous foot-bullet by pre-hashing, be careful that you don't pass raw binary to bcrypt, because it also truncates after NUL characters.

If you're worried about these problems, a temporary stopgap exists in password_lock.

In PHP 7.2, it will likely be possible to use Argon2i through this interface (assuming the RFC passes).

In a few years (circa PHP 7.5, assuming no major version bumps) we may see PASSWORD_ARGON2I become the new value for PASSWORD_DEFAULT, but maybe not. We've got a few years for cryptography researchers to gain confidence in it.

Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206
  • 2
    As mentioned in #2, you can defeat the 72-character limitation on Bcrypt by pre-hashing, ASCII-encoding the pre-hash, then sending that ASCII string to Bcrypt. Basically: `password_hash(base64_encode(hash('sha256', $password)), PASSWORD_DEFAULT);` – Aaron Toponce Sep 07 '16 at 18:21
  • @AaronToponce PHP's `hash` already returns a hex encoded string by default, so you can leave out the `base64_encode` – CodesInChaos Sep 08 '16 at 11:59
  • Or alternatively, pass `true` to `hash()`. The reason to base64 encode instead of hex encode is you can fit more possible values before the 72 char cutoff, but a SHA256 hash has more possible values than anyone will ever be able to iterate, let alone attempt for a bcrypt hash. – Scott Arciszewski Sep 08 '16 at 13:26
-2

I use Blowfish and really like it, but Keccak is said to be better.

"Better" is such a relative term. Better in what? Security, performance, scalability, portability, ... ?

If you want the greater "security" just for hashing user passwords, then Keccak is probably a not good option. Blowfish will give you better "security" as in it will take longer to brute-force the hash if the hash is ever discovered.

That being said, Keccak is a decent option if you're looking for something to run on embedded architecture, or if you want greater portability. Here is a PHP implementation on github, and here is another You can also make your own language extension by downloading the Keccak source.

But, honestly, it's probably best to stick with what you know. If a hacker can easily get the blowfish hashes you are currently using, then the problem is not the hashing algorithm but the access to the database. Also note that the PHP extension would have to be installed on ALL of the servers using this, which may or may not be possible if you're using a shared host.

In reality you should probably stick with what you have. Chances are it's safe enough, and once the Keccak implementation gets ported to the standard PHP core you can move then (if you need to). Just my two cents.

cegfault
  • 6,442
  • 3
  • 27
  • 49
  • 5
    Sorry, but this old accepted answer is wrong and potentially misleading. Keccak is a very fast hash, which means it can be bruteforced -- an attacker can test all candidate plaintext passwords in reasonable compute time. See the canonical answer on password storage: http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846 –  Aug 30 '13 at 16:02
  • @JesperMortensen: Keccak being fast does not hinder its use for password hashing. You can make it as slow as you want via iterations like Keccak(Keccak(Keccak(...(Keccak(password)||password)||...). But it's probably best to stick to recommended password hashing algorithms that already include such a "slowification". – sellibitze Oct 09 '13 at 15:49
  • 2
    Agree this answer is wrong and misleading - see this general answer, which also applies to SHA-3 and any other hashing algorithms not specifically intended for password hashing: http://stackoverflow.com/questions/401656/secure-hash-and-salt-for-php-passwords/8050063 – RichVel Mar 02 '14 at 14:05
  • 2
    Downvoted because this answer is most certainly wrong and misleading. The other answer by Eli Collins is the correct answer. Password hashing should always be used with a dedicated password hashing algorithm and an appropriate cost factor. In 2016, this is Argon2, scrypt, bcrypt, sha512crypt, sha256crypt, or PBKDF2. The threat model is password crackers with highly parallelizable GPUs, FPGAs, and ASICs. Using generic hashing functions, no matter how creative @sellibitze can be with a solution, is always wrong. – Aaron Toponce Sep 07 '16 at 16:46
  • 2
    @AaronToponce Most ad-hoc iteration schemes are no worse that PBKDF2 and sha2crypt and not as ugly (though @.sellibitze forgot the salt). Bcrypt&co on the other hand are better than any iterated generic hash. – CodesInChaos Sep 07 '16 at 17:22
  • 1
    Blowfish is a bad choice, bcrypt (which is referred to as `CRYPT_BLOWFISH`) is a great choice. Different algorithms. – Scott Arciszewski Sep 07 '16 at 17:32
  • @CodesInChaos I only disagree in that the cost is only an integer, versus building a manual for loop in the code, which likely would be hard-coded, and not configurable. The former introduces less chances for error and screwing things up versus the latter. But the end result is the same, indeed. – Aaron Toponce Sep 07 '16 at 17:38