PHP rewriting password hashing function what algo to use? - php

I'm rewriting my password hashing function.
It currently uses sha1.
I'm thinking about using sha512.
Am I right to think that sha512 is sha2?
Is this currently the standard for hashing passwords or should I use another hashing algo?

I would suggest using bcrypt to hash passwords.
This site gives some good background on the issue: http://codahale.com/how-to-safely-store-a-password/

SHA-2 uses four different bit sizes:
hash functions with digests that are 224, 256, 384 or 512 bits.

It should suffice to say whether bcrypt or SHA-512 is good enough. And the answer is yes, either algorithm is secure enough that a breach will occur through an implementation flaw, not cryptanalysis.
If you insist on knowing which is "better", SHA-512 has had in-depth by NIST and others. It's good, but flaws have been recognized that, while not exploitable now, have led to the the SHA-3 competition for new hash algorithms. Also, keep in mind that the study of hash algorithms is "newer" than that of ciphers, and cryptographers are still learning about them.
Even though bcrypt as a whole hasn't had as much scrutiny as Blowfish itself, I believe that being based on a cipher with a well-understood structure gives it some inherent security that hash-based authentication lacks.
So, my recommendation of bcrypt stems from the assumptions 1) that SHA-2 family of hash functions has better scrutiny, and 2) that cryptanalytic methods for ciphers are better developed than those for hash functions.

Related

C++ and PHP common password hash standard

I'm looking for a password hash standard that is easy to implement on php and c++. I know there is BCrypt but that really isn't that easy to implement on c++. Are there any hash algorithms that are easy to implement on both languages? I'm looking for this because I don't want my myBB forum cracked. They use md5 with salt which isn't really that good.
It doesn't protect me from being cracked. I know that. But if the forum is compromised I want a secure hash so they can't crack the passwords that easily.
Easy answer: Just use libsodium on both ends, then crypto_pwhash_str() in C/C++ and sodium_crypto_pwhash_str() in PHP. This gives you Argon2id, which is better than bcrypt given appropriate cost factors.
Even if it's tempting to "implement" crypto yourself, you're must better off using a standard implementation such as libsodium, libcrypto (part of OpenSSL), etc.
I suggest stronger algorithms such as SHA-256 or Blowfish. Even with MD5 salt it is weaker besides them.
However, whichever algorithm you use, use salt in your inputs. You can use both in php and c ++ effectively and easily.

Password Hashing, BCrypt to SHA1/MD5

I have been looking at upgrading the password hashing security of one of my applications as I have been reading up about brute force attacks being considerably faster then they used to. Currently I am using sha1(md5($password)) and I see the benefits of using bcrypt + salt. My question is, Would it be any more secure if I were to do the following:
Scenario 1:
$password -> sha1 -> bcrypt -> sha1
// This would enable me to keep all existing passwords and just
// regenerate all the hashes without waiting for the user to re login
Scenario 2:
$password -> bcrypt -> sha1
// I would have to add an extra column for the new hash until every
// user has logged in but the hash will still be sha1.
Would any of these two increase the security of the hash at all? I am no cryptographic master, far from it, I would just like a simple explanation as to if it would work, if not, and why.
Thanks
EDIT
After a little more reading, it seems that bcrypt is favoured because of its slowness in that i makes the cpu/gpu work longer before the hash is generated.
In the case of sha1 vs bcrypt, sha1 is roughly 300000 times faster then bcrypt. Which begs the question, if bcrypts advantage is slowness, surely a recursive hashing function which uses sha1 300000 times would be as secure as bcrypt?
I made this function as an example:
function bsha1($data, $salt) {
$hash = $data;
for ($i = 0; $i < 300000; ++$i) {
$hash = sha1($hash . $salt);
}
Provide it with a salt and itll return a sha1 hash where every iteration is a hashed hash and salt. This takes approximately the same ammount of time as bcrypt. Would this be as secure?
You best upgrade to password_hash().
As it is likely you are not using PHP 5.5 yet (I assume maybe you are already for testing purposes at this time), you can use the PHP userland implementation of password_hash() also written by Ircmaxell for PHP 5.3+.
To upgrade the password hashes on login, you fetch the hash from the database and test first against the new hashing. If it returns FALSE, you test against the old hashing. If that returns TRUE, you re-hash the password with the new new hashing and store it back into the database.
Combining or chaining multiple hashes after each other - and I fear I read that in your question - is a total stupidity you should never consider. Hash algorithms are not compatible to each other and using a hash on a hash that way is doing it wrong: sha1(md5($password)) and the like effectively reduce the output space which makes it easier to attack - something you want prevent in the future.
So take the new password hashing API that there is in PHP and sleep well.
neither scenario gives you much of a security margin over just bcrypt. That said, bcrypt is absolutely the way to go as far as a hashing algorithm that will resist brute forcing, as with a sufficiently high cost factor, it will take a much longer time to hash than any SHA-based hashing scheme.
Saying all that, Scenario 1 may be the way to go, as you are able to secure your db now instead of piecemeal as users log in. Despite what M8R-1jmw5r says in his/her answer, combining hashing algorithms doesn't give you any extra security, but it also won't really impact your security negatively.
You can use any standard hashing algorithm, but being standard hashing function they can be backtracked and there is a potential security risk.
You better go with any hash functions but combine it with salt with your personal keys. here is link
http://www.php.net/manual/en/faq.passwords.php#faq.passwords.fasthash
Short answer is yes it would help. However the long answer is no because SHA-1 and MD5 are just weak hashing algorithms now. It would be better for you to just go with SHA-2 algorithms or even wait a little longer and go directly to SHA-3.
The problem is in the hashing function. Three layers will definitely stop someone, but honestly most of the time one layer is enough to get most people to not even bother. If someone is very intent on getting in I would use SHA-2 at the very least other wise you should be fine with what you have.
EDIT::
Ok so to clarify the above. Using SHA1 with Bcrypt is not necesarilly the best way to go. I would use SHA-2 algorithms with bcrypt instead, this would give you more security than using the SHA-1. Also by layers I mean the Bcrypt is one Hash pass the SHA-1 is one Hash pass the second SHA-1 is another Hash pass. I really don't understand why this is wrong? Sorry for the difference in semantics about the layers.
EDIT2::
$Password -> Bcrypt -> SHA-2 or Bcrypt(SHA-2($Password)) Where SHA-2 is one of the SHA-2 family of hashing algorithms.
Code to be more clear than Bcrypt with SHA-2 instead of SHA-1.

Salting Passwords and in particular about the database and retrieving the password

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.
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 php. It's built-in. Scrypt isn't.
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

PHP Cryptography Good Practices?

So I heard md5() and sha1() are both outdated and potentially broken. I've heard that crypt() isn't a viable solution as well.
If that's the case, can anyone point out what are the current up to date cryptography good practices in PHP? I've searched the web but didn't find anything that looked up to date/potential.
Hash plus salt alone is outdated, too, and generally no longer endorsed in password hashing schemes. It's too easy to calculate such hashes in parallel (even with individual per-user salts), a resourceful attacker is most likely able to break such a scheme.
You should use some form of iterative hashing instead. In addition to applying salts to your passwords, such an algorithm artificially slows the entire hashing process down (cryptographic hashes are generally designed to be as fast as possible while upholding a fixed "security margin"). Suitable primitives to reach this goal are generally considered to be the bcrypt, scrypt or PBKDF2 algorithms. See for example this answer for a discussion on how to use bcrypt in PHP.

How long should my password salt be, and is SHA-256 good enough?

I'm in the process of creating a gaming community site that I'm aiming to release to the public soon. Currently, I'm working on passwords and logins. I've only used MD5 before, but I've read about password safety and heard that salting is currently the way to go.
Here's my plan: Every user has their own unique salt of 12 random characters (#/¤& etc), stored in the users table. The salt is hashed (using SHA-256) along with the password on registration, and re-hashed on login.
How does this sound to you? Anything I can improve? Should I go for SHA-512 and a longer salt, or is this enough?
Your suggestion of 12 bytes should be an adequate length for a salt. That would require a dictionary attack to prepare 296 databases of hashed passwords. Someday this might be a trivial operation for a cracker, but we're still a ways off from that.
SHA256 is recommended by NIST as having adequate hashing strength for passwords, at least for now.
If you want to explore even stronger methods of password security, look into key-strengthening techniques like PBKDF2, or adaptive hashing with Bcrypt. But these have no direct support in SQL. You'd have to do the hashing in application code and then post the hash digest to your database.
It may seem like security overkill for a gaming site, but it's a good practice to do it. Because many users (inadvisably) use the same password for their gaming login as they do for their banking login! You don't want to be responsible for an authentication breach that leads indirectly to major losses.
Update:
Don't use hashing or HMAC. Use bcrypt or scrypt. See http://codahale.com/how-to-safely-store-a-password/
Original:
Don't simply hash. Use HMAC. (And avoid doing your own hashing or crypto if there is a library available, since libraries benefit from expert input.)
References:
http://rdist.root.org/2009/10/29/stop-using-unsafe-keyed-hashes-use-hmac/
http://us2.php.net/manual/en/function.hash-hmac.php
It's probably sufficient for your use case.
However, it could be improved by:
Increase the size of the salt
The salt should be not be limited to a small subset of characters
Iterate the hashing, say 1000 times (key strengthening)
Have a look at phpass.
I've noticed a lot of confusion about how to do password hashing properly, especially on stackoverflow. And I've seen some REALLY BAD recommendations. So I've written a page that should clear everything up. There's a bit more to it than using a simple hash.
More info and source code: How to do password hashing properly
Feel free to share this link whenever someone has a question about password hashing. This is my first post on stackoverflow so sorry if I'm not doing it right
If you are really concerned, I would look at using the whirlpool hashing function instead of one of the SHA variants. Whirlpool has proven to be an incredibly strong hashing method, and has no history of collisions or any other weaknesses (that I know of, at least).
You can use whirlpool by employing the hash function of PHP. (Note, however, that hash() requires PHP 5.1.2 or greater.)
Your current approach is enough.

Categories