What is a current, functional replacement for md5 cryptography in PHP? - php

I hear md5 is long dated and obselete. What are my alternative options?
Many thanks.

I recommened you to use SHA-2 family. The SHA-2 family of hash functions are the current replacement of SHA-1. The members of SHA-2 are individually referred to as SHA-224, SHA-256, SHA-384, and SHA-512.
For a hash, you basically just want to choose the largest block size possible, and use a salt value to avoid rainbow attacks.
if you need to replace MD5 in an application where using a hash was a bad design choice in the first place, which include many uses in conjunction with password (protection of login information, or generation of a key from a password), then you do not want just to replace MD5; you want to change the design.

Google pbkdf2. There are implementations in PHP out there, and it's a one-stop-shop for complete password protection. If you're just hashing the password and then done with it, md5 is a little worse than sha1, which is a little worse than sha256, etc, but they're all vulnerable to rainbow tables. Make sure you're using proper salting techniques at minimum, and to really do it right you should use an algorithm like pbkdf2, the object of which is to make it computationally intensive to brute force (with a dash of obscurity in there as well, since it requires the attacker to know the number of iterations you're using, not just the algorithm).

Related

Correct Code Procedure For Storing Passwords Securing Passwords In MYSQL

So currently my code is using a standard sha1 to hash the password for database implementation.
What is or is there a better more securing way to store the password? Maybe MD5 (Yes I am joking)
For example I am using Codeigniter as my framework, What would be the best way to encrypt the passwords?
I would do it this way.
salt = For each user generate a random seed with a random length.
iterations = Select a random number
while(iterations != 0) {
hashed_password = hash_function(password.salt) . salt; iterations-- }
in the password field save them like so:
hashed_password:salt:hash_function:iterations.
And at login use the new password in combination with salt, hash_function and iteration to hash it and compare the result with the hashed_password.
off course you can use multiple hash functions to like sha_x(md5(salt.password).salt).salt or what ever you want but make sure that you save it in some way in order to make the comparison at login.
You should really use bcrypt to hash your passwords, it was designed especially for hashing password.
Hash functions for passwords should be slow (need some computing time). Most hash algorithms like SHA-1 and MD5 or even SHA-256 are designed to be fast, but this makes it an easy target for brute force attacks.
Don't be afraid to use bcrypt! It is not for high security sites only, and using it can be as easy, as using an md5 hash. It's recommended to use a well established library like phpass, and if you want to understand how it works, you can read this article, where i tried to explain the most important points.
This lib is very good: http://www.openwall.com/phpass/
It uses the crypt method with various algorithms and also has it's own based on md5 but with so many iterations and salt that it's "safe".
SHA1 was brocken in 2005
February 15, 2005
SHA-1 Broken
SHA-1 has been broken. Not a reduced-round version. Not a simplified
version. The real thing.
The research team of Xiaoyun Wang, Yiqun Lisa Yin, and Hongbo Yu
(mostly from Shandong University in China) have been quietly
circulating a paper describing their results: collisions in the the
full SHA-1 in 2*69 hash operations, much less than the brute-force
attack of 2*80 operations based on the hash length.
collisions in SHA-0 in 2**39 operations.
collisions in 58-round SHA-1 in 2**33 operations.
Take a look at this comparisoion list.

Improve password hashing with a random salt

I'm starting a website and I'm trying to decide how to encrypt user passwords to store them in a SQL database.
I realize that using a simple md5(password) is very unsecured. I'm considering using a sha512(password.salt), and I have been researching the best way to generate a useful salt.
I read numerous articles stating that a salt should be as random as possible to add entropy to the hash and it looks like a great idea. But:
you need to store the random salt along with your hash
given that an attacker somehow got access to your hashed passwords (and is trying to reverse the hash to plain text), it means he probably dumped your database, then got access to your random salts also
Isn't it obvious that the weird looking value next to the hash in the database is a salt? If the attacker can access the salt along with the hash value, how is that more secure?
Anyone has any expertise in that area? Thanks!
An attacker is "allowed" to know the salt - your security must be designed in a way that even with the knowledge of the salt it is still secure.
What does the salt do ?
Salt aids in defending against brute-force attacks using pre-computed "rainbow-tables".
Salt makes brute-force much more expensive (in time/memory terms) for the attacker.
Calculating such a table is expensive and usually only done when it can be used for more than one attack/password.
IF you use the same salt for all password an attacker could pre-compute such a table and then brute-force your passwords into cleartext...
As long as you generate a new (best cryptogrpahically strong) random salt for every password you want to store the hash of there is no problem.
IF you want to strengthen the security further
You could calculate the hash several times over (hash the hash etc.) - this doesn't cost you much but it makes a brute-force attack / calculating "rainbow-tables" even more expensive... please don't invent yourself - there are proven standard methods to do so, see for example http://en.wikipedia.org/wiki/PBKDF2 and http://www.itnewb.com/tutorial/Encrypting-Passwords-with-PHP-for-Storage-Using-the-RSA-PBKDF2-Standard
NOTE:
Using such a mechanism is these days mandatrory since "CPU time" (usable for attacks like rainbow tables/brute force etc.) is getting more and more widely available (see for example the fact that Amazon's Cloud service is among the top 50 of fastest supercomuters worldwide and can be used by anyone for a comparatively small amount)!
given that an attacker somehow got access to your hashed passwords
(and is trying to reverse the hash to plain text), it means he
probably dumped your database, then got access to your random salts
also
The whole point of salting is to defeat "rainbow tables":
http://en.wikipedia.org/wiki/Rainbow_table
See why a sufficiently long salt defeats any rainbow table under the section "Defense against rainbow tables".
how is that more secure?
It used to be more secure because it forced the attacker to try a, back then, very costly brute-force approach instead of an instant looked in precomputed rainbow tables. If you had a 64 bit salt, the attacker needed to have 2^64 precomputed rainbow tables instead of one... In other words: it made rainbow tables useless.
Note however that modern GPUs can crack billions of passwords per second making it mostly pointless for an attacker to store huge rainbow tables (instead of storing billions of hashes, simply compute them in a few seconds).
Nowadays you want to store your "passwords" using something like PBKDF2 or scrypt.
The strength of your hashed, salted passwords rely on all of the following factors:
The strength of the hashing algorithm
The randomness of the salt
The randomness of the password
Your system is as strong as the weakest of the above.
The questions below are from the sister site Security StackExchange. They discuss hashing, salts, PBKDF2, bcrypt, scrypt, and a few other things.
How to securely hash passwords?
Do any security experts recommend bcrypt for password storage?
There's also some previous discussion from here on StackOverflow as well:
Is BCrypt a good hashing algorithm to use in C#? Where can I find it?
In short answer to you question, a salt is a safeguard that makes it take a long time to recover a password in the event of compromise just as a hash is. If attacking one password, the salt won't make a difference. If trying to use a pre-computed dictionary or test many passwords at the same time, having a different salt for each entry will greatly increase the amount of work needed and generally make generating a suitable rainbow table infeasible.
Here's a good article on cryptography: http://www.javacodegeeks.com/2012/02/introduction-to-strong-cryptography-p1.html
See the section Real World Usage of Hash Algorithms, Scenario 1 for discussion of the salt.
I highly recommend using http://docs.oracle.com/javase/6/docs/api/java/security/SecureRandom.html to generate your salt

Securely hash passwords - so much conflicting advice!

I'm reading so much conflicting advice as to how to store passwords securely. All I know for sure is not to use MD5! I've seen people advocate using PHP's bcrypt function, which seems like it'd hog the server's processor. I've seen advocates for salts, and advocates for not using salts.
It's all just so unclear. Is there real and credible advice as to how to store passwords securely?
Edit: After a fair amount of research, I found an article from ;login: that deals with the topic in quite some depth: http://www.usenix.org/publications/login/2004-06/pdfs/alexander.pdf
Well, there is several parts to this.
You need to try to make it difficult to get to your db and passwords in the first place, keep them secure. This includes not making your passwords cleartext and not using a symmetric encryption algorithm.
You need to use a salt. Doing this prevents people from using a precomputed lookup table (i.e. rainbow table) or something like http://md5.rednoize.com/. Pick some data for your salt that is both unique and unpredictable. I usually use a random 32 bit value, but I wouldn't go much less.
Some algorithms are stronger than others. This is defined in a couple ways
How fast it can be computed. Longer is better. The faster the attacker can calculate hashes, the better the odds are for a bruteforce attack.
If the algorithm has no known weakness which reduce the search space. For example, the number of bits in an md5 hash is misleading because there are known attacks that reduce the actual search space
As of today I think SHA1 or SHA2 with a salt is reasonably secure for the near future. There is a utility called bcrypt which uses an asymmetric variant of blowfish and has the concepts of salt and computational expense built-in, it might be worth checking out.
Edit: I wanted to clarify what a salt is, as there is a lot of misconception about it on SO and online.
What a Salt is not
A secret, pre-agreed upon string that you hash with the password. This is a secret key, not a salt.
What a Salt is
You include the salt (unique and unpredictable per hash) along with your password when hashing, but you also include a unencrypted copy of it outside of your hash, so that when verifying the hash later you are able to include the same salt when given a test password before hashing it so you can properly compare the hash.
The point of bycrpt is to hog the processor! (Relatively speaking.) It is for this reason that it is "better" for password hashing than SHA1/2. (This "better" assumes that the password hashes are already in the hands of the attacker or otherwise exposed; while it would nice if it were not the case, even big corporations have had security compromises.)
This requirement was explicitly considered for bcrypt -- if you can only process 1k hashes a second (still, that's a good bit of log-in attempts), how long will that take an attacker to brute-force? A good bit longer than if they could process 10 million hashes a second! The target attack space of a brute-force that is only of the allowed password input, which is often much smaller -- esp. in practice with "simple passwords" -- than the space of the hash!
And a salt is very much required to avoid rainbow tables which trade time for space :) A rainbow table would effectively need to be created for each unique salt value. (Thus, the more unique salt values, the more space is required and with enough values this becomes impractical for an attacker.)
Happy coding.
First of all you need to use a good hash function, I suggest SHA-256. You can create a SHA-256 hash like this:
$hash = hash('sha256', $password);
In addition you could also use salting like this:
$salt = 'salt here';
$hash = hash('sha256', $salt . $password);
Moreover, you can use HMACs, like this:
$secret = 'your secret';
$hmac = hash_hmac('sha256', $password, $secret);
The best way to create solid hashes is through salting and iteration.
You should loop the above functions until hashing takes 200ms.
You could also go ahead and use encryption, but that would be a bit overkill for most situations.
This is similar to this question: Methods for storing login information in database
Credible advice: Never store your passwords in clear text!
Beyond that you have some choices to make. As I mentioned in the response to the linked question, there are two camps: let some else store your authentication data or do it your self. If you decide to do it your self, then you need to come up with a hashing routine. This should probably include a salting your passwords.
You can use sha256. A good thing to do is to add extra information to the password such as username, userid, or some other data to it. This way, if someone hack your database, it will be impossible to use an existant hash database to find the password. They will have to crack the password starting from zero.

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.

How should I incorporate the salt in my password hash?

How much stronger would
return sha1($salt.sha1($passwd));
be compared to just:
return sha1($salt.$passwd);
$salt is a per-user string of length 12 consisting of strong random ASCII.
It's exactly twice as strong, because the attacker needs to perform twice as many SHA1 calculations for a brute force attack.
Of course, that is still not exactly impressive. On the other hand, doing the SHA1 5000 times in a loop is practical for authorization, but makes attacks take 5000 times longer - this technique is known as key strengthening. It is, however, really just a poor man's substitute for the adaptible-cost hash algorithms that Jacco mentions.
At first glance, and without strong knowledge in crypto, I'd say it's not stronger at all.
By the way, it's usually advised to use
sha1($login.$salt.$passwd);
so that 2 users with the same password won't have the same hash.
As far as I know there is no difference in strength.
Since it is common practice to prepend the salt to the password hash, the salt is generally known to an attacker. But this does not defeat the purpose of the salt.
It is generally speaking not a a good idead to add the $login/$username to the hash (Vinzz's solution) as it will cause problems if the user changes his or her username. A better solution is to use a random salt.
The used hashing algorithm does make a difference. SHA1 is considered cryptographically broken and should not be used to hash passwords.
Gennerally speaking BCRYPT (a Blowfish based adaptable-cost hashing algorithm) is considdered best to be the practice (CRYPT_BLOWFISH flag for PHP's crypt();)
Other solid options are SHA256 and above.
Edit:
I wrote a longer answer on salting here: stackoverflow.com/questions/1645161/salt-generation-and-open-source-software/

Categories