FAQ
在线手册:中文  英文

Safe Password Hashing

This section explains the reasons behind using hashing functions to secure passwords, as well as how to do so effectively.

  1. Why should I hash passwords supplied by users of my application?
  2. Why are common hashing functions such as md5 and sha1 unsuitable for passwords?
  3. How should I hash my passwords, if the common hash functions are not suitable?
  4. What is a salt?
Why should I hash passwords supplied by users of my application?

Password hashing is one of the most basic security considerations that must be made when designing any application that accepts passwords from users. Without hashing, any passwords that are stored in your application's database can be stolen if the database is compromised, and then immediately used to compromise not only your application, but also the accounts of your users on other services, if they do not use unique passwords.

By applying a hashing algorithm to your user's passwords before storing them in your database, you make it implausible for any attacker to determine the original password, while still being able to compare the resulting hash to the original password in the future.

It is important to note, however, that hashing passwords only protects them from being compromised in your data store, but does not necessarily protect them from being intercepted by malicious code injected into your application itself.

Why are common hashing functions such as md5() and sha1() unsuitable for passwords?

Hashing algorithms such as MD5, SHA1 and SHA256 are designed to be very fast and efficient. With modern techniques and computer equipment, it has become trivial to "brute force" the output of these algorithms, in order to determine the original input.

Because of how quickly a modern computer can "reverse" these hashing algorithms, many security professionals strongly suggest against their use for password hashing.

How should I hash my passwords, if the common hash functions are not suitable?

When hashing passwords, the two most important considerations are the computational expense, and the salt. The more computationally expensive the hashing algorithm, the longer it will take to brute force its output.

There are two functions that are bundled with PHP that can perform hashing using a specified algorithm.

The first hashing function is crypt(), which natively supports several hashing algorithms. When using this function, you are guaranteed that the algorithm you select is available, as PHP contains native implementations of each supported algorithm, in case one or more are not supported by your system.

The second hashing function is hash(), which supports many more algorithms and variants than crypt(), but does not support some algorithms that crypt() does. The Hash extension is bundled with PHP, but can be disabled during compile-time, so it is not guaranteed to be available, while crypt() is, being in the PHP core.

The suggested algorithm to use when hashing passwords is Blowfish, as it is significantly more computationally expensive than MD5 or SHA1, while still being scalable.

What is a salt?

A cryptographic salt is data which is applied during the hashing process in order to eliminate the possibility of the output being looked up in a list of pre-calculated pairs of hashes and their input, known as a rainbow table.

In more simple terms, a salt is a bit of additional data which makes your hashes significantly more difficult to crack. There are a number of services online which provide extensive lists of pre-computed hashes, as well as the original input for those hashes. The use of a salt makes it implausible or impossible to find the resulting hash in one of these lists.


FAQ
在线手册:中文  英文

用户评论:

sgbeal at googlemail dot com (2012-09-19 13:21:38)

sha1 in conjunction with one or more salt values need not be as insecure as the above makes it out to be. e.g. the Fossil SCM creates an sha1 password hash based on a user's clear-text password combined with the user's name and a shared secret known only to the specific source repository for which the user is set up.

fluffy at beesbuzz dot biz (2012-06-11 23:33:49)

The security issue with simple hashing (md5 et al) isn't really the speed, so much as the fact that it's idempotent; two different people with the same password will have the same hash, and so if one person's hash is brute-forced, the other one will as well. This facilitates rainbow attacks. Simply slowing the hash down isn't a very useful tactic for improving security. It doesn't matter how slow and cumbersome your hash algorithm is - as soon as someone has a weak password that's in a dictionary, EVERYONE with that weak password is vulnerable.
Also, hash algorithms such as md5 are for the purpose of generating a digest and checking if two things are probably the same as each other; they are not intended to be impossible to generate a collision for. Even if an underlying password itself requires a lot of brute forcing to determine, that doesn't mean it will be impossible to find some other bit pattern that generates the same hash in a trivial amount of time.
As such: please, please, PLEASE only use salted hashes for password storage. There is no reason to implement your own salted hash mechanism, either, as crypt() already does an excellent job of this.

alice2287 at live dot com (2012-03-13 16:25:48)

For those wishing to increase the computational cost of brute-forcing their password hashes by iterating the hash command multiple times, but don't want to increase the risk of a hash collision, simply re-append the password to the hash each iteration.

<?php

$iterations 
10;
$hash crypt($password,$salt);
for (
$i 0$i $iterations; ++$i)
{
    
$hash crypt($hash $password,$salt);
}

?>

This, of course, can be used with md5(), sha1(), etc. as well as crypt().

Some other recommendations:

- Use the highest number of iterations possible without introducing a significantly noticeable delay to authenticating users, or causing more CPU use than your host will allow.
- Use a unique salt for each user, ideally a random one.
- Use a salt of at least 24 bytes, especially if you're using a weaker algorithm like MD5 or SHA-1.

易百教程