1

I want to create a membership site so i want to make the passwords as safe as possible. I can see from reading sites including this one the md5, sh1 encryption are a serious no no. I've seen some other things like bcript, scrypt, sha256, sha512 and PBKDF2. I have found some php scripts implementing these but not really found anything of note to do with the database.

Do i have to create a row containing the salt?

Verifying the password do i have to do something like hash(salt+password) = $hash?

Because i'm not the most experienced at passwords i'm not really sure of the best practices, how when you hash the password + salt what happens then, how the passwords are retrieved...

I think because i dont really understand the logic behind it i'm feeling a little confused about how to go about it.

MrGoodKat
  • 58
  • 8
  • If I understand you well, I think, this article will be useful for you: http://crackstation.net/hashing-security.htm – SaidbakR Dec 16 '12 at 15:13
  • If you choose bcrypt in particular, make space for at least 60 characters in your column :) – Ja͢ck Dec 16 '12 at 15:18
  • Thanks for the help everyone! – MrGoodKat Dec 16 '12 at 15:31
  • Here ya go, have a simple wrapper lib for bcrypt functionality in php 5.3 plus: https://gist.github.com/1151912 – Kzqai Dec 16 '12 at 16:34
  • @Tchalvak: I think you're supposed to use `2y` instead of `2a` now for some reason or other. http://www.php.net/security/crypt_blowfish.php – Ry- Dec 16 '12 at 16:37
  • Hmmm, that's going to be annoying to react to, thanks for pointing it out, I'll update the gist when I'm off mobile. – Kzqai Dec 16 '12 at 16:46
  • 1
    Read [How to securely hash passwords?](http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords) Then read [How to store salt?](http://security.stackexchange.com/questions/17421/how-to-store-salt) and [Do any security experts recommend bcrypt for password storage?](http://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage) and more generally [questions about passwords on Security Stack Exchange](http://security.stackexchange.com/questions/tagged/passwords?sort=votes). – Gilles 'SO- stop being evil' Dec 16 '12 at 21:14
  • `2` and some `2a` `bcrypt` had issues. So `2y` now indicates a "good" `2a` hash, while `2x` indicates a "bad" `2a` hash. bcrypt is a hyped mess. – Has QUIT--Anony-Mousse Dec 16 '12 at 22:26
  • Look into [The definitive guide to forms based website authentication](http://stackoverflow.com/q/549/1741542), which is pretty comprehensive. – Olaf Dietsche Dec 16 '12 at 23:26

2 Answers2

4

If you use Bcrypt, Scrypt, or PBKDF2, the salt is part of the hash you get, so no, you don't have to worry about storing it separately. Otherwise (SHA-*), yes — but you shouldn't use those anyways. Bcrypt, Scrypt, and PBKDF2 are actual password-hashing functions.

I'd recommend Bcrypt, since you tagged this . It's built-in. Scrypt isn't.

Ry-
  • 199,309
  • 51
  • 404
  • 420
  • Built in after php 5.3, that is. – Kzqai Dec 16 '12 at 15:15
  • I recommend using an extensible scheme, such as that of `crypt`. That is also highly portable. – Has QUIT--Anony-Mousse Dec 16 '12 at 15:43
  • @Anony-Mousse: Yep - Bcrypt is `crypt` with `2y` as an ID. – Ry- Dec 16 '12 at 15:48
  • But `bcrypt` is not included in standard glibc. crypt-SHA512 however is included, with a default of 5000 rounds. And if you read the story of `2y` vs. `2x` vs `2`, there already were some screwups in the bcrypt codebase... – Has QUIT--Anony-Mousse Dec 18 '12 at 00:29
  • @Anony-Mousse: It's included in PHP, and PHP is what we're using here. And yes, there have been minor mistakes in the past, but... they're fixed, and that's life. Hence the extensibility. – Ry- Dec 18 '12 at 00:32
  • Even when your web site is PHP, you may at some point want to also use components written in other languages. `crypt` is very portable, you can switch to other systems at any point. – Has QUIT--Anony-Mousse Dec 18 '12 at 07:10
  • @Anony-Mousse: Wanna go Ruby? There's a gem for that. Python? Package for that. Node? Package for that. C? Source for that. – Ry- Dec 18 '12 at 16:04
  • The unix standard for authentication is PAM. It's everywhere. The default module does not support bcrypt. It *does* support SHA-512 with 5000+ rounds. Without all the hype, no misinformation. – Has QUIT--Anony-Mousse Dec 18 '12 at 16:55
  • @Anony-Mousse: What does that have to do with my comment? – Ry- Dec 18 '12 at 19:25
  • If you can get something equivalent for free by sticking to the default authentication mechanisms, why bother to install some package for *anything*? – Has QUIT--Anony-Mousse Dec 19 '12 at 00:19
  • @Anony-Mousse: Er... that would be because Bcrypt is better. – Ry- Dec 19 '12 at 02:32
  • Only if you ignore that `crypt` *does* use multiple rounds of SHA-512. Any proof that `bcrypt` is more secure than `SHA-512` when you scale them to the same computation time by choosing appropriate number of rounds? – Has QUIT--Anony-Mousse Dec 19 '12 at 09:09
  • @Anony-Mousse: Yes, the GPU factor. Breaking even multiple rounds of SHA-512 on a GPU is relatively easy. Bcrypt, not so much. Anyway, I'm not against SHA-512 with multiple rounds; it's great. One round of anything is the real problem (as seen below). I'm just saying that if you're using `crypt` anyways, why not use Bcrypt if it does make attacks harder at the moment and is still upgradable? – Ry- Dec 19 '12 at 19:05
  • Because `bcrypt` is not supported in default PAM. – Has QUIT--Anony-Mousse Dec 19 '12 at 22:05
  • @Anony-Mousse: Mmmkay. Do we need it to be supported in default PAM? Well, no, not since PHP 5.3. We're not using it to log onto a computer. In other languages, installing some kind of package is painless and makes things more convenient than just having it "in default PAM". – Ry- Dec 20 '12 at 02:52
1

A common best practise (see e.g. Linux passwd) is to store the password hashes as

$<algorithm>$<salt>$<hash>

for example this string:

$6$Lxgyf7h6DtkrqwT$0w/BoB6neYjEtdQdUEs3ftnnNguBNTug8.g/9UeMmZ9bN/cDJCE0dj8.4D/8HPN5bMqFPJ4ECnGl5M2iqBmmv/

is a salted SHA-512 (algorithm id 6) password hash salted with Lxgyf7h6DtkrqwT that should be understood by most servers out of the box.

The benefit of this is that you can actually support different algorithms at the same time. So some users may still have e.g. SHA-256 passwords, while for any user changing his password you switch to a more secure algorithm.

A good starting point to read about modular hashing schemes, read this article in Wikipedia on the crypt (Unix) function. The hype around bcrypt (and the misinformation that crypt would equal DES hashing) is indicative of a certain naiveness of PHP developers with respect to password security. bcrypt is not bad (well, it relies on computational complexity instead of stronger algorithms AFAIK, but it certainly seems to beat MD5). But I would advise using something like this scheme which is A) portable, and B) extensible, so that you can at any time smoothly transition to stronger password hashes.

In 99% of programming languages (including PHP), this functionality is available out of the box via the crypt function, by choosing an appropriate salt, starting with $6$ and the appropriate length of salt characters.

And to clean up some of the misinformation systematically spread by bcrypt advocates: this is not using just one round of sha-512, but the default apparently (see http://www.akkadia.org/drepper/sha-crypt.html ) is 5000 rounds of SHA-512. And you can choose to increase the number. So for my understanding the "but bcrypt can be scaled up when needed" claim also holds for crypt-SHA512. In contrast to bcrypt, this should be available on any Linux system using glibc 2.7 onward. bcrypt is an extension only available on some distributions or with some extensions. On Debian and probably Ubuntu you apparently need to install the extension

libpam-unix2 - Blowfish-capable PAM module

Has QUIT--Anony-Mousse
  • 70,714
  • 12
  • 123
  • 184
  • Cheers for that @Anony-Mousse. I think i get it a bit better! Think i have a fair bit of reading to do to understand everything better! – MrGoodKat Dec 16 '12 at 15:30
  • 1
    The hype around BCrypt has it's good reasons. With common hardware you can calculate 200 Mega SHA-512 hashes per second, that makes only 3 milliseconds to brute-force a whole english dictionary with about 500'000 words! I would like to invite you to read this tutorial about [secure password hashing](http://www.martinstoeckli.ch/hash/en/index.php). – martinstoeckli Dec 17 '12 at 10:44
  • But as your `root` password is probably not bcyrpt encrypted, you are busted anyway. – Has QUIT--Anony-Mousse Dec 17 '12 at 11:06
  • Plus, and that is my main concern, bcrypt seems to largely rely that current GPUs don't help much **yet**. And this *yet* is what is dangerous about bcrypt. I've seen reports that say they get 41x speed ups using CUDA for actual data encryption. Now an encryption scheme relying on the GPUs *not* getting better caches and instructions over time is IMHO really dangerous, and "security by obscurity (of operations)". But as I'm not an crypto expert, I think it is best to rely on what the libc provides, and trust them to add appropiate algorithms as necessary. And bcrypt is not standard yet. – Has QUIT--Anony-Mousse Dec 17 '12 at 12:36
  • 1
    @Anony-Mousse - Not sure what you mean with `root` password, you don't need a root password for hashing passwords. If you mean a pepper, that is only an addition to the hashing and should not influence the quality of the hashing. BCrypt is good because of the _adaptable cost factor_, this you cannot wipe away with GPU's and caches. You can do the same with iterating SHA-512 hashes, it is called _PBKDF2_. – martinstoeckli Dec 17 '12 at 18:52
  • What I'm referring to is the fact that most Linux distributions don't use `bcrypt` for their system accounts. I see little sense in pushing the security of a PHP web application beyond the security of the *underlying operating system*. And the problem with the *adaptable cost factor* is that if we do already see 40x speed gains in GPU cracking, and thus increase the cost factor, but do not see comparable gains in CPU hashing, we *do* at some point run into the problem that you need dedicated servers with GPUs just for validating logins. – Has QUIT--Anony-Mousse Dec 17 '12 at 19:22
  • Which then may mean we are going to see consumer hardware acceleration for hash functions next... – Has QUIT--Anony-Mousse Dec 17 '12 at 19:23
  • 1
    @Anony-Mousse - BCrypt protects passwords, whose hashes are _already stolen_, this has nothing to do with how easy an attacker can get control over a server. Even when he controls the server and has the database with hashes, he cannot get the original passwords. The problem with CPU vs GPU you have in every case, but even if you need one millisecond on a GPU, it makes brute forcing unpracticable. This makes a difference of 200'000'000 versus 1 calculations, for other SHA-X algorithms even more. – martinstoeckli Dec 17 '12 at 20:13
  • If he has control over the server, he can log the passwords prior to hashing... at the cost of brute-forcing a single hash, if he got that one. So the root password hash (if not using a crypto key) clearly is much more important than any PHP database hashes. So, does it really make sense to use a hash your OS does not use? – Has QUIT--Anony-Mousse Dec 17 '12 at 22:45
  • @Anony-Mousse: How would an attacker get that hash? The database containing hashes and salts can generally be read by the PHP user, and could even be dumped by SQL injection. Accessing `/etc/shadow`, on the other hand, would require root access (in which case it's pointless, except to get a password to try elsewhere, maybe). And trying a bunch of passwords over, say, SSH, would be really slow. (Not to mention the fact that OSes should be using Bcrypt anyways.) So I'd say that yes, it makes sense to use a hash that your OS doesn't use. – Ry- Dec 17 '12 at 23:26
  • 1
    And once again, bcrypt is available out of the box, using the same `crypt` function with a different hash ID, except it's waaaay more secure. (And not "hyped" at all.) The misinformation here is that SHA-2 is better than SHA-1 or MD5 for password hashing. They're not; I can break SHA-2 hashes at more or less the same speed as I can MD5. The only reason MD5 is discouraged as a general-purpose hash is because it's vulnerable to intentional collision attacks. – Ry- Dec 17 '12 at 23:27
  • Only on OpenBSD and maybe SuSE Linux seem to use bcrypt for the operating system. Official glibc 2.7 seems to only support DES, MD5, SHA-256 and SHA-512. So it seems as if at least the glibc maintainers do not consider bcrypt to be a good idea. – Has QUIT--Anony-Mousse Dec 17 '12 at 23:47
  • Judging by http://www.akkadia.org/drepper/sha-crypt.html it is btw. common (as in: implemented in official glibc 2.7) to not do 1 round of SHA-512, but 5000 as default, and this can be increased. – Has QUIT--Anony-Mousse Dec 18 '12 at 00:22
  • @Anony-Mousse - Hey that's what i meant with PBKDF2! It doesn't matter if you use BCrypt or PBKDF2, both have this advantage of an adaptable cost factor. You could even use MD5 if you are iterating, though that does not make much sense of course. – martinstoeckli Dec 18 '12 at 08:22