faq/passwords.xml
f012b2761819e0ab25ff8cf4bac6655cfbc6fcff
...
...
@@ -1,165 +1,159 @@
1
1
<?xml version="1.0" encoding="utf-8"?>
2
2
<!-- $Revision$ -->
3
3
<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>
5
5
<titleabbrev>Password Hashing</titleabbrev>
6
6
7
-
<para>
7
+
<simpara>
8
8
This section explains the reasons behind using hashing functions
9
9
to secure passwords, as well as how to do so effectively.
10
-
</para>
10
+
</simpara>
11
11
12
12
<qandaset>
13
13
<qandaentry xml:id="faq.passwords.hashing">
14
14
<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>
18
18
</question>
19
19
<answer>
20
-
<para>
20
+
<simpara>
21
21
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
27
27
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
32
32
determine the original password, while still being able to compare
33
33
the resulting hash to the original password in the future.
34
-
</para>
35
-
<para>
34
+
</simpara>
35
+
<simpara>
36
36
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>
41
41
</answer>
42
42
</qandaentry>
43
43
<qandaentry xml:id="faq.passwords.fasthash">
44
44
<question>
45
-
<para>
45
+
<simpara>
46
46
Why are common hashing functions such as <function>md5</function> and
47
47
<function>sha1</function> unsuitable for passwords?
48
-
</para>
48
+
</simpara>
49
49
</question>
50
50
<answer>
51
-
<para>
51
+
<simpara>
52
52
Hashing algorithms such as MD5, SHA1 and SHA256 are designed to be
53
53
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,
55
55
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
59
59
algorithms, many security professionals strongly suggest against
60
60
their use for password hashing.
61
-
</para>
61
+
</simpara>
62
62
</answer>
63
63
</qandaentry>
64
64
<qandaentry xml:id="faq.passwords.bestpractice">
65
65
<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
68
68
not suitable?
69
-
</para>
69
+
</simpara>
70
70
</question>
71
71
<answer>
72
-
<para>
72
+
<simpara>
73
73
When hashing passwords, the two most important considerations are the
74
74
computational expense, and the salt. The more computationally expensive
75
75
the hashing algorithm, the longer it will take to brute force its
76
76
output.
77
-
</para>
78
-
<para>
79
-
PHP 5.5 provides
77
+
</simpara>
78
+
<simpara>
79
+
PHP provides
80
80
<link linkend="book.password">a native password hashing API</link> that
81
81
safely handles both <link linkend="function.password-hash">hashing</link>
82
82
and <link linkend="function.password-verify">verifying passwords</link>
83
-
in a secure manner. There is also
84
-
<link xlink:href="&url.password.compat;">a pure PHP compatibility library</link>
85
-
available for PHP 5.3.7 and later.
86
-
</para>
87
-
<para>
88
-
Another option is the <function>crypt</function> function, which
89
-
supports several hashing algorithms in PHP 5.3 and later. When using
90
-
this function, you are guaranteed that the algorithm you select is
91
-
available, as PHP contains native implementations of each supported
92
-
algorithm, in case one or more are not supported by your system.
93
-
</para>
94
-
<para>
83
+
in a secure manner.
84
+
</simpara>
85
+
<simpara>
95
86
The suggested algorithm to use when hashing passwords is Blowfish, which
96
87
is also the default used by the password hashing API, as it is
97
88
significantly more computationally expensive than MD5 or SHA1, while
98
89
still being scalable.
99
-
</para>
100
-
<para>
101
-
Note that if you are using <function>crypt</function> to verify a
102
-
password, you will need to take care to prevent timing attacks by using
103
-
a constant time string comparison. Neither PHP's
104
-
<link linkend="language.operators.comparison">== and === operators</link>
105
-
nor <function>strcmp</function> perform constant time string
106
-
comparisons. As <function>password_verify</function> will do this for
107
-
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
108
96
<link linkend="book.password">native password hashing API</link>
109
97
whenever possible.
110
-
</para>
98
+
</simpara>
111
99
</answer>
112
100
</qandaentry>
113
101
<qandaentry xml:id="faq.passwords.salt">
114
102
<question>
115
-
<para>
103
+
<simpara>
116
104
What is a salt?
117
-
</para>
105
+
</simpara>
118
106
</question>
119
107
<answer>
120
-
<para>
108
+
<simpara>
121
109
A cryptographic salt is data which is applied during the hashing process
122
110
in order to eliminate the possibility of the output being looked up
123
111
in a list of pre-calculated pairs of hashes and their input, known as
124
112
a rainbow table.
125
-
</para>
126
-
<para>
113
+
</simpara>
114
+
<simpara>
127
115
In more simple terms, a salt is a bit of additional data which makes
128
-
your hashes significantly more difficult to crack. There are a number of
116
+
hashes significantly more difficult to crack. There are a number of
129
117
services online which provide extensive lists of pre-computed hashes, as
130
118
well as the original input for those hashes. The use of a salt makes it
131
119
implausible or impossible to find the resulting hash in one of these
132
120
lists.
133
-
</para>
134
-
<para>
121
+
</simpara>
122
+
<simpara>
135
123
<function>password_hash</function> will create a random salt if one
136
124
isn't provided, and this is generally the easiest and most secure
137
125
approach.
138
-
</para>
126
+
</simpara>
139
127
</answer>
140
128
</qandaentry>
141
129
<qandaentry xml:id="faq.password.storing-salts">
142
130
<question>
143
-
<para>
144
-
How do I store my salts?
145
-
</para>
131
+
<simpara>
132
+
How are salts stored?
133
+
</simpara>
146
134
</question>
147
135
<answer>
148
-
<para>
136
+
<simpara>
149
137
When using <function>password_hash</function> or
150
138
<function>crypt</function>, the return value includes the salt as part
151
-
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
152
140
database, as it includes information about the hash function that was
153
141
used and can then be given directly to
154
-
<function>password_verify</function> or <function>crypt</function> when
155
-
verifying passwords.
156
-
</para>
157
-
<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>
158
152
The following diagram shows the format of a return value from
159
-
<function>crypt</function> or <function>password_hash</function>. As you
160
-
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
161
155
algorithm and salt required for future password verification.
162
-
</para>
156
+
</simpara>
163
157
<para>
164
158
<mediaobject>
165
159
<alt>
166
160