Skip to content

Commit f012b27

Browse files
authored
Tweak the title and depersonalize the password hashing FAQ section (#3796)
Also streamlines the mentions of `crypt()` and discourages its use
1 parent 5cc10e8 commit f012b27

1 file changed

Lines changed: 72 additions & 77 deletions

File tree

faq/passwords.xml

Lines changed: 72 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,159 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<!-- $Revision$ -->
33
<chapter xml:id="faq.passwords" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
4-
<title>Safe Password Hashing</title>
4+
<title>Hashing passwords safely and securely</title>
55
<titleabbrev>Password Hashing</titleabbrev>
66

7-
<para>
7+
<simpara>
88
This section explains the reasons behind using hashing functions
99
to secure passwords, as well as how to do so effectively.
10-
</para>
10+
</simpara>
1111

1212
<qandaset>
1313
<qandaentry xml:id="faq.passwords.hashing">
1414
<question>
15-
<para>
16-
Why should I hash passwords supplied by users of my application?
17-
</para>
15+
<simpara>
16+
Why should passwords supplied by users be hashed?
17+
</simpara>
1818
</question>
1919
<answer>
20-
<para>
20+
<simpara>
2121
Password hashing is one of the most basic security considerations that
22-
must be made when designing any application that accepts passwords
23-
from users. Without hashing, any passwords that are stored in your
24-
application's database can be stolen if the database is compromised, and
25-
then immediately used to compromise not only your application, but also
26-
the accounts of your users on other services, if they do not use
22+
must be made when designing any application or service that accepts passwords
23+
from users. Without hashing, any passwords that are stored
24+
can be stolen if the data store is compromised, and
25+
then immediately used to compromise not only the application or service, but also
26+
the accounts of users on other services, if they do not use
2727
unique passwords.
28-
</para>
29-
<para>
30-
By applying a hashing algorithm to your user's passwords before storing
31-
them in your database, you make it implausible for any attacker to
28+
</simpara>
29+
<simpara>
30+
By applying a hashing algorithm to the user's passwords before storing
31+
them, it becomes implausible for any attacker to
3232
determine the original password, while still being able to compare
3333
the resulting hash to the original password in the future.
34-
</para>
35-
<para>
34+
</simpara>
35+
<simpara>
3636
It is important to note, however, that hashing passwords only protects
37-
them from being compromised in your data store, but does not necessarily
38-
protect them from being intercepted by malicious code injected into your
39-
application itself.
40-
</para>
37+
them from being compromised in the data store, but does not necessarily
38+
protect them from being intercepted by malicious code injected into the
39+
application or service itself.
40+
</simpara>
4141
</answer>
4242
</qandaentry>
4343
<qandaentry xml:id="faq.passwords.fasthash">
4444
<question>
45-
<para>
45+
<simpara>
4646
Why are common hashing functions such as <function>md5</function> and
4747
<function>sha1</function> unsuitable for passwords?
48-
</para>
48+
</simpara>
4949
</question>
5050
<answer>
51-
<para>
51+
<simpara>
5252
Hashing algorithms such as MD5, SHA1 and SHA256 are designed to be
5353
very fast and efficient. With modern techniques and computer equipment,
54-
it has become trivial to "brute force" the output of these algorithms,
54+
it has become trivial to <quote>brute force</quote> the output of these algorithms,
5555
in order to determine the original input.
56-
</para>
57-
<para>
58-
Because of how quickly a modern computer can "reverse" these hashing
56+
</simpara>
57+
<simpara>
58+
Because of how quickly a modern computer can <quote>reverse</quote> these hashing
5959
algorithms, many security professionals strongly suggest against
6060
their use for password hashing.
61-
</para>
61+
</simpara>
6262
</answer>
6363
</qandaentry>
6464
<qandaentry xml:id="faq.passwords.bestpractice">
6565
<question>
66-
<para>
67-
How should I hash my passwords, if the common hash functions are
66+
<simpara>
67+
How should passwords be hashed, if the common hash functions are
6868
not suitable?
69-
</para>
69+
</simpara>
7070
</question>
7171
<answer>
72-
<para>
72+
<simpara>
7373
When hashing passwords, the two most important considerations are the
7474
computational expense, and the salt. The more computationally expensive
7575
the hashing algorithm, the longer it will take to brute force its
7676
output.
77-
</para>
78-
<para>
77+
</simpara>
78+
<simpara>
7979
PHP provides
8080
<link linkend="book.password">a native password hashing API</link> that
8181
safely handles both <link linkend="function.password-hash">hashing</link>
8282
and <link linkend="function.password-verify">verifying passwords</link>
8383
in a secure manner.
84-
</para>
85-
<!-- TODO Drop mention of crypt? -->
86-
<para>
87-
Another option is the <function>crypt</function> function, which
88-
supports several hashing algorithms. When using
89-
this function, you are guaranteed that the algorithm you select is
90-
available, as PHP contains native implementations of each supported
91-
algorithm, in case one or more are not supported by your system.
92-
</para>
93-
<para>
84+
</simpara>
85+
<simpara>
9486
The suggested algorithm to use when hashing passwords is Blowfish, which
9587
is also the default used by the password hashing API, as it is
9688
significantly more computationally expensive than MD5 or SHA1, while
9789
still being scalable.
98-
</para>
99-
<para>
100-
Note that if you are using <function>crypt</function> to verify a
101-
password, you will need to take care to prevent timing attacks by using
102-
a constant time string comparison. Neither PHP's
103-
<link linkend="language.operators.comparison">== and === operators</link>
104-
nor <function>strcmp</function> perform constant time string
105-
comparisons. As <function>password_verify</function> will do this for
106-
you, you are strongly encouraged to use the
90+
</simpara>
91+
<simpara>
92+
The <function>crypt</function> function is also available for password
93+
hashing, but it is only recommended for interoperability with other
94+
systems.
95+
Instead, it is strongly encouraged to use the
10796
<link linkend="book.password">native password hashing API</link>
10897
whenever possible.
109-
</para>
98+
</simpara>
11099
</answer>
111100
</qandaentry>
112101
<qandaentry xml:id="faq.passwords.salt">
113102
<question>
114-
<para>
103+
<simpara>
115104
What is a salt?
116-
</para>
105+
</simpara>
117106
</question>
118107
<answer>
119-
<para>
108+
<simpara>
120109
A cryptographic salt is data which is applied during the hashing process
121110
in order to eliminate the possibility of the output being looked up
122111
in a list of pre-calculated pairs of hashes and their input, known as
123112
a rainbow table.
124-
</para>
125-
<para>
113+
</simpara>
114+
<simpara>
126115
In more simple terms, a salt is a bit of additional data which makes
127-
your hashes significantly more difficult to crack. There are a number of
116+
hashes significantly more difficult to crack. There are a number of
128117
services online which provide extensive lists of pre-computed hashes, as
129118
well as the original input for those hashes. The use of a salt makes it
130119
implausible or impossible to find the resulting hash in one of these
131120
lists.
132-
</para>
133-
<para>
121+
</simpara>
122+
<simpara>
134123
<function>password_hash</function> will create a random salt if one
135124
isn't provided, and this is generally the easiest and most secure
136125
approach.
137-
</para>
126+
</simpara>
138127
</answer>
139128
</qandaentry>
140129
<qandaentry xml:id="faq.password.storing-salts">
141130
<question>
142-
<para>
143-
How do I store my salts?
144-
</para>
131+
<simpara>
132+
How are salts stored?
133+
</simpara>
145134
</question>
146135
<answer>
147-
<para>
136+
<simpara>
148137
When using <function>password_hash</function> or
149138
<function>crypt</function>, the return value includes the salt as part
150-
of the generated hash. This value should be stored verbatim in your
139+
of the generated hash. This value should be stored verbatim in the
151140
database, as it includes information about the hash function that was
152141
used and can then be given directly to
153-
<function>password_verify</function> or <function>crypt</function> when
154-
verifying passwords.
155-
</para>
156-
<para>
142+
<function>password_verify</function> when verifying passwords.
143+
</simpara>
144+
<warning>
145+
<simpara>
146+
<function>password_verify</function> should always be used instead
147+
of re-hashing and comparing the result to a stored hash in order
148+
to avoid timing attacks.
149+
</simpara>
150+
</warning>
151+
<simpara>
157152
The following diagram shows the format of a return value from
158-
<function>crypt</function> or <function>password_hash</function>. As you
159-
can see, they are self-contained, with all the information on the
153+
<function>crypt</function> or <function>password_hash</function>. As can
154+
be seen, they are self-contained, with all the information on the
160155
algorithm and salt required for future password verification.
161-
</para>
156+
</simpara>
162157
<para>
163158
<mediaobject>
164159
<alt>

0 commit comments

Comments
 (0)