Skip to content

Commit

Permalink
Tweak the title and depersonalize the password hashing FAQ section (#…
Browse files Browse the repository at this point in the history
…3796)

Also streamlines the mentions of `crypt()` and discourages its use
  • Loading branch information
jimwins authored Oct 1, 2024
1 parent 5cc10e8 commit f012b27
Showing 1 changed file with 72 additions and 77 deletions.
149 changes: 72 additions & 77 deletions faq/passwords.xml
Original file line number Diff line number Diff line change
@@ -1,164 +1,159 @@
<?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>Safe Password Hashing</title>
<title>Hashing passwords safely and securely</title>
<titleabbrev>Password Hashing</titleabbrev>

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

<qandaset>
<qandaentry xml:id="faq.passwords.hashing">
<question>
<para>
Why should I hash passwords supplied by users of my application?
</para>
<simpara>
Why should passwords supplied by users be hashed?
</simpara>
</question>
<answer>
<para>
<simpara>
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
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.
</para>
<para>
By applying a hashing algorithm to your user's passwords before storing
them in your database, you make it implausible for any attacker to
</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.
</para>
<para>
</simpara>
<simpara>
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.
</para>
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>
<para>
<simpara>
Why are common hashing functions such as <function>md5</function> and
<function>sha1</function> unsuitable for passwords?
</para>
</simpara>
</question>
<answer>
<para>
<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 "brute force" the output of these algorithms,
it has become trivial to <quote>brute force</quote> the output of these algorithms,
in order to determine the original input.
</para>
<para>
Because of how quickly a modern computer can "reverse" these hashing
</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.
</para>
</simpara>
</answer>
</qandaentry>
<qandaentry xml:id="faq.passwords.bestpractice">
<question>
<para>
How should I hash my passwords, if the common hash functions are
<simpara>
How should passwords be hashed, if the common hash functions are
not suitable?
</para>
</simpara>
</question>
<answer>
<para>
<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.
</para>
<para>
</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.
</para>
<!-- TODO Drop mention of crypt? -->
<para>
Another option is the <function>crypt</function> function, which
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.
</para>
<para>
</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.
</para>
<para>
Note that if you are using <function>crypt</function> to verify a
password, you will need to take care to prevent timing attacks by using
a constant time string comparison. Neither PHP's
<link linkend="language.operators.comparison">== and === operators</link>
nor <function>strcmp</function> perform constant time string
comparisons. As <function>password_verify</function> will do this for
you, you are strongly encouraged to use the
</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.
</para>
</simpara>
</answer>
</qandaentry>
<qandaentry xml:id="faq.passwords.salt">
<question>
<para>
<simpara>
What is a salt?
</para>
</simpara>
</question>
<answer>
<para>
<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.
</para>
<para>
</simpara>
<simpara>
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
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.
</para>
<para>
</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.
</para>
</simpara>
</answer>
</qandaentry>
<qandaentry xml:id="faq.password.storing-salts">
<question>
<para>
How do I store my salts?
</para>
<simpara>
How are salts stored?
</simpara>
</question>
<answer>
<para>
<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 your
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> or <function>crypt</function> when
verifying passwords.
</para>
<para>
<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 you
can see, they are self-contained, with all the information on the
<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.
</para>
</simpara>
<para>
<mediaobject>
<alt>
Expand Down

0 comments on commit f012b27

Please sign in to comment.