This question already has answers here:
Secure hash and salt for PHP passwords
(14 answers)
Closed 9 years ago.
I'm using PHP. I want a safe and fast password encryption system. Hashing a password a million times may be safer, but also slower. How to achieve a good balance between speed and safety?
I want to know the best encryption method in php and how to apply it.
I recommend using the new PHP 5.5 password API. It provides a secure means of hashing a password, while being fast enough.
If you don't have PHP 5.5 available there is a polyfill that works with PHP 5.3.7+: https://github.com/ircmaxell/password_compat
Use PHPass, it is an excellent hashing framework and very easy to use!
Use SHA512 http://php.net/manual/en/function.hash.php.
SHA512 is not cracked. I suggest to use a salt: Some random string that you append to the password before hashing. This can protect against precomputed rainbow tables but not against dictionary attacks if the attacker gains access to the database containing passwords and salts.
SHA512(password + salt) --> hash
Store hash and salt in the DB
When checking password, retrieve salt corresponding to user, concatenate it with password, hash it and compare it with stored hash.
Read here: How long to brute force a salted SHA-512 hash? (salt provided)
Thinking back about your question and particularly about your statement "Hashing a password a million times may be safer, but also slower. How to achieve a good balance between speed and safety". Indeed, repeatedly hashing will protect you against dictionary attacks by making it computationally prohibitively expensive to compute all hashes in a dictionary. I am not teaching you anything here. From the first link I gave you, it took around 46 milliseconds to calculate a SHA512 hash, which is relatively long. Out of hand I can think of the following factors that could influence your decision as you are in an arms race setting:
- Increasing computing power (more CPU cores and GPU computations)
- Improved Algorithms over time
- Amount of money available to the attacker
- The value to get out of your site if cracked (if low, it would not be worth the effort)
against
- Amount of CPU power you have at your disposal
As a rule of thumb, I would hash as many times as possible so as to not impact my web site performance. Taking into account the number of logins per seconds, you can roughly calculate the amount of CPU power you can afford to spend without impacting your site performance.
One last comment: Assuming hackers already have access to the table containing the user names and hashed passwords, you might at that point be more worried about all the bad things they can do on your site.
your not looking for encryption - your looking for hashing.
I suggest openwalls phpass http://www.openwall.com/phpass/
If you are using PHP5.5 they have a password hasing API
http://uk3.php.net/password
for more info.
MD5 (salt-less) has been used for a while a large number of lookup lists are around, Combined with modern hardware getting 700K + passwords per second it wont take long at all to "reverse" the password.
With a salt they are more secure, But still can be cracked quickly
Related
In light of how many major websites have been hacked and their databases of password decrypted what is the best way to secure authentication?
Basically I am interested in a way to secure access to a part of a site to members in a way that if hacked would under no circumstances let hackers get a hold of the user's passwords.
Nothing is invulnerable but at least make it very difficult to crack.
http://codahale.com/how-to-safely-store-a-password/
Use bcrypt
Use bcrypt.
Use bcrypt.
Use bcrypt.
Use bcrypt.
Use bcrypt.
Use bcrypt.
Use bcrypt.
Use bcrypt.
Use bcrypt.
Why Not {MD5, SHA1, SHA256, SHA512, SHA-3, etc}?
These are all general purpose hash functions, designed to calculate a digest
of huge amounts of data in as short a time as possible. This means that they are
fantastic for ensuring the integrity of data and utterly rubbish for storing
passwords.
A modern server can calculate the MD5 hash of about
330MB every second. If your
users have passwords which are lowercase, alphanumeric, and 6 characters long,
you can try every single possible password of that size in around
40 seconds.
And that’s without investing anything.
If you’re willing to spend about 2,000 USD and a week or two picking up
CUDA, you can put together your
own little supercomputer cluster which will let you
try around 700,000,000 passwords a second.
And that rate you’ll be cracking those passwords at the rate of more than one
per second.
Salts Will Not Help You
It’s important to note that salts are useless for preventing dictionary
attacks or brute force attacks. You can use huge salts or many salts or
hand-harvested, shade-grown, organic Himalayan pink salt.
It doesn’t affect how fast an attacker can try a candidate password, given the
hash and the salt from your database.
Salt or no, if you’re using a general-purpose hash function designed for speed
you’re well and truly effed.
bcrypt Solves These Problems
How? Basically, it’s slow as hell. It uses a variant of the Blowfish
encryption algorithm’s keying schedule, and introduces a work factor, which
allows you to determine how expensive the hash function will be. Because of
this, bcrypt can keep up with Moore’s law. As computers get faster you can
increase the work factor and the hash will get slower.
How much slower is bcrypt than, say, MD5? Depends on the work factor. Using
a work factor of 12, bcrypt hashes the password yaaa in about 0.3 seconds on
my laptop. MD5, on the other hand, takes less than a microsecond.
So we’re talking about 5 or so orders of magnitude. Instead of cracking a
password every 40 seconds, I’d be cracking them every 12 years or so. Your
passwords might not need that kind of security and you might need a faster
comparison algorithm, but bcrypt allows you to choose your balance of speed
and security. Use it.
Besides proper password handling (like bcrypt, as already mentioned), you need to do the password hashing on a dedicated device/machine.
This "device" for password hashing is a separate system which contains so called "local parameter", which is an extra input to the hash function (say, 128-bit strong random number). This local parameter must be unreadable by the host system (your app, which does the user authentication).
Using such a dedicated machine for password hashing buys you an extra layer of security if your password database/app gets compromised.
I'm looking into hash and salting passwords using bcrypt in PHP.
Can someone explain to me why brcypt's use of "work" / "rounds" prevents attacks?
I've already read "How do you use bcrypt for hashing passwords in PHP?", but I'm having a hard time understanding what makes it so special if someone got a hold of your database and could crack it offline?
Would it be potentially up to the salt and hash together to protect the database against rainbow tables? Or does bcrypt do something special to help prevent attacks like this?
Simply put bcrypt is "better" than some other hash algorithms like the sha family because it's purposely slow and can be made purposely slower by using a high iteration count. Futhermore, it requires the use of a salt which protects against the use of pre-caclulated hash values (rainbow tables). The salt value should be generated/stored together with each output of bcrypt to disallow comparisions between values of different users (in case they use the same password).
Even if an attacker gets your password hashes and salts, as long as your use of bcrypt is using a high number of iterations, it won't be possible to quickly find the matching password. It is a one way function so you would need to perform the bcrypt calculations once for each password that is tried. This is of course little protection against bad passwords.
In a nutshell, bcrypt and other password stretching algorithms are all about work amplification. An attacker has to do a lot more work to crack a password than you have to (since you typically only get valid login requests or mistaken passwords, at a much lower rate); thus, every millisecond you add to password hashing time your attacker has to pay a million or a billion times over. Bcrypt and other algorithms simply slow things down deliberately, making your attacker spend a lot more time trying to crack passwords.
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
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is “double hashing” a password less secure than just hashing it once?
So, I was reading an article on securing PHP websites and they recommended hashing a password multiple times, in fact, this is a direct quote from the article:
md4(md4(md5(sha1(md4(md5(sha1(sha1($_POST['password']))))))));
Now, personally, I generally use a salted SHA-256 hash on my passwords, because I thought that MD4 and MD5 were no longer secure and that hashing a password multiple times would just put too much strain on a server for no practical benefit. Is that correct?
The direct quote from the article wouldn't work, as there is no md4() function in PHP. And then it wouldn't make sense still.
Normally applying multiple hashing functions wouldn't hurt. But when you go from sha1 to md5 you are losing input range (md5 gives you 128 bit output, but sha1 is 160 bits long). This is rehashing a shortened excerpt, which means the possible output set is never bigger than that of md5().
If you don't hash your passwords tens of thousands of times, you don't know what you are doing.
This is computationally expensive; that is the point. For the legitimate purpose of authenticating a user who has the correct password, the load is negligible. But for a cracker who is trying to test a huge list of passwords in an offline attack, the cost is prohibitive.
Using thousands of iterations of a hash function is a well-established and widely used technique for "key strengthening." It is incorporated in standards for key derivation, and used in algorithms like bcrypt for password protection.
Use bcrypt or PBKDF2, which will require you to use salt and iterations. Don't try to make up your own method using a few broken hashes.
A bit. If the goal is to actually get the original password, it becomes an impossible task. However, usually it is not, and if you really use md4 for the outermost hash, well.. http://en.wikipedia.org/wiki/MD4#Security
There are many other ways to improve security, the most basic of which is to use some kind of random salt that is not stored along with the password.
I have a user table in my mysql database that has a password column. Currently, I use the MD5 algorithm to hash the users' password for storage in the database. Now I like to think that I am a security conscience person. I noticed while reading the MySQL docs that they don't recommend MD5 or the SHA/SHA1 hashing methods, but don't offer an alternative.
What would be the best way to hash my passwords in MySQL? A function that is natively supported in both PHP and MySQL would be ideal and necessary with my current implementation.
Thanks!
It's not necessarily that you shouldn't use MD5, as much it's that you shouldn't use just MD5, as this leaves you vulnerable to rainbow-table attacks (a rainbow table is a table of precomputed hash values - if your password is even remotely common or simple, the attacker needs merely to look up the hash and he knows your plaintext password.)
At the very least you should add a salt to every password so that any existing rainbow table is useless, forcing the attacker to generate an entire new rainbow table just for your database of passwords.
Better still is to use a different salt for every password in your database, say the username it's associated with, so that an attacker can't even generate a rainbow table for your whole database and has to crack each entry separately.
MD5 is also a very fast algorithm. Speed is the enemy when it comes to cracking - the longer it takes to generate a hash, the longer it takes for each attempt a hacker makes. Something simple like hashing the plaintext 100 times with a new additional salt each time would be barely perceptible (if at all) to a user logging in to your site, but it would increase the time it takes to brute-force a password by the same 100 times.
Far, far more detail here: http://www.codinghorror.com/blog/archives/000953.html
MD5 is considered to be weak by today's standards. It would still take some work to crack a hash made with MD5, but it's several times easier than guessing the password by brute-force. Ideally, cracking a hash should not be easier than brute-force.
SHA1 is also considered easier to crack than guessing the password by brute-force.
I actually contributed a patch to MySQL to surface the SHA224, SHA256, SHA384, and SHA512 functions from OpenSSL. These are recommended by NIST for password hashing (actually SHA256 and higher).
My patch was finished by MySQL engineers, and is included in MySQL 6.0.5 and later, if I recall.
If you use an earlier version of MySQL (and who doesn't), then you can probably use an implementation of strong hashing functions in your host language. PHP has the hash() function for example. You can do the hashing in your application and save the resulting message string to the database.
Don't forget to do salting, too!
This question is 7 years old. In that time we have progressed in computing to where MD5 and SHA1 are now easily broken by modern computers. These should be avoided now.
With PHP 5.5 came the introduction of password_hash, which uses the far more secure bcrypt algorithm. While MySQL can encrypt/decrypt bcrypt, it's a terrible solution because you're not only adding a potentially large computation load to your database layer, but the unhashed password could be stored in your logs
Under no circumstances should a plain text password hit MySQL, even if at the query level. Otherwise you risk writing the passwords to log (query log, general log, slow query log, etc). Which is horrific. So no, don't even bother...
MD5 and SHA-1 probably aren't recommended anymore due to know attacks. But, they're still generally sufficient for most use cases.
If you're looking for more options, just use PHP's hash functions -- you've got plenty of options there.
I am using a combination. For example SHA1(MD5()) is working fine.