mirror of
https://github.com/php/doc-en.git
synced 2026-03-23 23:32:18 +01:00
195 lines
7.0 KiB
XML
195 lines
7.0 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<chapter xml:id="faq.passwords" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Hashing passwords safely and securely</title>
|
|
<titleabbrev>Password Hashing</titleabbrev>
|
|
|
|
<simpara>
|
|
This section explains the reasons behind using hashing functions
|
|
to secure passwords, as well as how to do so effectively.
|
|
</simpara>
|
|
|
|
<qandaset>
|
|
<qandaentry xml:id="faq.passwords.hashing">
|
|
<question>
|
|
<simpara>
|
|
Why should passwords supplied by users be hashed?
|
|
</simpara>
|
|
</question>
|
|
<answer>
|
|
<simpara>
|
|
Password hashing is one of the most basic security considerations that
|
|
must be made when designing any application or service that accepts passwords
|
|
from users. Without hashing, any passwords that are stored
|
|
can be stolen if the data store is compromised, and
|
|
then immediately used to compromise not only the application or service, but also
|
|
the accounts of users on other services, if they do not use
|
|
unique passwords.
|
|
</simpara>
|
|
<simpara>
|
|
By applying a hashing algorithm to the user's passwords before storing
|
|
them, it becomes 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.
|
|
</simpara>
|
|
<simpara>
|
|
It is important to note, however, that hashing passwords only protects
|
|
them from being compromised in the data store, but does not necessarily
|
|
protect them from being intercepted by malicious code injected into the
|
|
application or service itself.
|
|
</simpara>
|
|
</answer>
|
|
</qandaentry>
|
|
<qandaentry xml:id="faq.passwords.fasthash">
|
|
<question>
|
|
<simpara>
|
|
Why are common hashing functions such as <function>md5</function> and
|
|
<function>sha1</function> unsuitable for passwords?
|
|
</simpara>
|
|
</question>
|
|
<answer>
|
|
<simpara>
|
|
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 <quote>brute force</quote> the output of these algorithms,
|
|
in order to determine the original input.
|
|
</simpara>
|
|
<simpara>
|
|
Because of how quickly a modern computer can <quote>reverse</quote> these hashing
|
|
algorithms, many security professionals strongly suggest against
|
|
their use for password hashing.
|
|
</simpara>
|
|
</answer>
|
|
</qandaentry>
|
|
<qandaentry xml:id="faq.passwords.bestpractice">
|
|
<question>
|
|
<simpara>
|
|
How should passwords be hashed, if the common hash functions are
|
|
not suitable?
|
|
</simpara>
|
|
</question>
|
|
<answer>
|
|
<simpara>
|
|
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.
|
|
</simpara>
|
|
<simpara>
|
|
PHP provides
|
|
<link linkend="book.password">a native password hashing API</link> that
|
|
safely handles both <link linkend="function.password-hash">hashing</link>
|
|
and <link linkend="function.password-verify">verifying passwords</link>
|
|
in a secure manner.
|
|
</simpara>
|
|
<simpara>
|
|
The suggested algorithm to use when hashing passwords is Blowfish, which
|
|
is also the default used by the password hashing API, as it is
|
|
significantly more computationally expensive than MD5 or SHA1, while
|
|
still being scalable.
|
|
</simpara>
|
|
<simpara>
|
|
The <function>crypt</function> function is also available for password
|
|
hashing, but it is only recommended for interoperability with other
|
|
systems.
|
|
Instead, it is strongly encouraged to use the
|
|
<link linkend="book.password">native password hashing API</link>
|
|
whenever possible.
|
|
</simpara>
|
|
</answer>
|
|
</qandaentry>
|
|
<qandaentry xml:id="faq.passwords.salt">
|
|
<question>
|
|
<simpara>
|
|
What is a salt?
|
|
</simpara>
|
|
</question>
|
|
<answer>
|
|
<simpara>
|
|
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.
|
|
</simpara>
|
|
<simpara>
|
|
In more simple terms, a salt is a bit of additional data which makes
|
|
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.
|
|
</simpara>
|
|
<simpara>
|
|
<function>password_hash</function> will create a random salt if one
|
|
isn't provided, and this is generally the easiest and most secure
|
|
approach.
|
|
</simpara>
|
|
</answer>
|
|
</qandaentry>
|
|
<qandaentry xml:id="faq.password.storing-salts">
|
|
<question>
|
|
<simpara>
|
|
How are salts stored?
|
|
</simpara>
|
|
</question>
|
|
<answer>
|
|
<simpara>
|
|
When using <function>password_hash</function> or
|
|
<function>crypt</function>, the return value includes the salt as part
|
|
of the generated hash. This value should be stored verbatim in the
|
|
database, as it includes information about the hash function that was
|
|
used and can then be given directly to
|
|
<function>password_verify</function> when verifying passwords.
|
|
</simpara>
|
|
<warning>
|
|
<simpara>
|
|
<function>password_verify</function> should always be used instead
|
|
of re-hashing and comparing the result to a stored hash in order
|
|
to avoid timing attacks.
|
|
</simpara>
|
|
</warning>
|
|
<simpara>
|
|
The following diagram shows the format of a return value from
|
|
<function>crypt</function> or <function>password_hash</function>. As can
|
|
be seen, they are self-contained, with all the information on the
|
|
algorithm and salt required for future password verification.
|
|
</simpara>
|
|
<para>
|
|
<mediaobject>
|
|
<alt>
|
|
The components of the value returned by password_hash and crypt: in
|
|
order, the chosen algorithm, the algorithm's options, the salt used,
|
|
and the hashed password.
|
|
</alt>
|
|
<imageobject>
|
|
<imagedata fileref="en/faq/figures/crypt-text-rendered.svg" width="690" depth="192" format="SVG" />
|
|
</imageobject>
|
|
</mediaobject>
|
|
</para>
|
|
</answer>
|
|
</qandaentry>
|
|
</qandaset>
|
|
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|