reference/password/functions/password-hash.xml
c6b95280cf10b6b252683ee7d86416c4c27deb4e
...
...
@@ -1,4 +1,4 @@
1
-
<?xml version="1.0" encoding="utf-8"?>
1
+
<?xml version="1.0" encoding="utf-8"?>
2
2
<!-- $Revision$ -->
3
3

4
4
<refentry xml:id="function.password-hash" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
...
...
@@ -12,14 +12,12 @@
12
12
<methodsynopsis>
13
13
<type>string</type><methodname>password_hash</methodname>
14
14
<methodparam><type>string</type><parameter>password</parameter></methodparam>
15
-
<methodparam><type>integer</type><parameter>algo</parameter></methodparam>
16
-
<methodparam choice="opt"><type>array</type><parameter>options</parameter></methodparam>
15
+
<methodparam><type class="union"><type>string</type><type>int</type><type>null</type></type><parameter>algo</parameter></methodparam>
16
+
<methodparam choice="opt"><type>array</type><parameter>options</parameter><initializer>[]</initializer></methodparam>
17
17
</methodsynopsis>
18
18
<para>
19
19
<function>password_hash</function> creates a new password hash using a strong one-way hashing
20
-
algorithm. <function>password_hash</function> is compatible with <function>crypt</function>.
21
-
Therefore, password hashes created by <function>crypt</function> can be used with
22
-
<function>password_hash</function>.
20
+
algorithm.
23
21
</para>
24
22
<simpara>
25
23
The following algorithms are currently supported:
...
...
@@ -41,37 +39,83 @@
41
39
create the hash. This will produce a standard <function>crypt</function> compatible hash using
42
40
the "$2y$" identifier. The result will always be a 60 character string, &return.falseforfailure;.
43
41
</simpara>
42
+
</listitem>
43
+
<listitem>
44
+
<simpara>
45
+
<constant>PASSWORD_ARGON2I</constant> - Use the Argon2i hashing algorithm to create the hash.
46
+
This algorithm is only available if PHP has been compiled with Argon2 support.
47
+
</simpara>
48
+
</listitem>
49
+
<listitem>
50
+
<simpara>
51
+
<constant>PASSWORD_ARGON2ID</constant> - Use the Argon2id hashing algorithm to create the hash.
52
+
This algorithm is only available if PHP has been compiled with Argon2 support.
53
+
</simpara>
54
+
</listitem>
55
+
</itemizedlist>
56
+
</para>
57
+
<simpara>
58
+
Supported options for <constant>PASSWORD_BCRYPT</constant>:
59
+
</simpara>
60
+
<para>
61
+
<itemizedlist>
62
+
<listitem>
44
63
<para>
45
-
Supported Options:
64
+
<literal>salt</literal> (<type>string</type>) - to manually provide a salt to use when hashing the password.
65
+
Note that this will override and prevent a salt from being automatically generated.
66
+
</para>
67
+
<para>
68
+
If omitted, a random salt will be generated by <function>password_hash</function> for
69
+
each password hashed. This is the intended mode of operation.
70
+
</para>
71
+
<warning>
72
+
<para>
73
+
The salt option is deprecated. It is now
74
+
preferred to simply use the salt that is generated by default.
75
+
As of PHP 8.0.0, an explicitly given salt is ignored.
76
+
</para>
77
+
</warning>
78
+
</listitem>
79
+
<listitem>
80
+
<para>
81
+
<literal>cost</literal> (<type>int</type>) - which denotes the algorithmic cost that should be used.
82
+
Examples of these values can be found on the <function>crypt</function> page.
83
+
</para>
84
+
<para>
85
+
If omitted, a default value of <literal>10</literal> will be used. This is a good
86
+
baseline cost, but you may want to consider increasing it depending on your hardware.
87
+
</para>
88
+
</listitem>
89
+
</itemizedlist>
90
+
</para>
91
+
<simpara>
92
+
Supported options for <constant>PASSWORD_ARGON2I</constant>
93
+
and <constant>PASSWORD_ARGON2ID</constant>:
94
+
</simpara>
95
+
<para>
96
+
<itemizedlist>
97
+
<listitem>
98
+
<para>
99
+
<literal>memory_cost</literal> (<type>int</type>) - Maximum memory (in kibibytes) that may
100
+
be used to compute the Argon2 hash. Defaults to <constant>PASSWORD_ARGON2_DEFAULT_MEMORY_COST</constant>.
101
+
</para>
102
+
</listitem>
103
+
<listitem>
104
+
<para>
105
+
<literal>time_cost</literal> (<type>int</type>) - Maximum amount of time it may
106
+
take to compute the Argon2 hash. Defaults to <constant>PASSWORD_ARGON2_DEFAULT_TIME_COST</constant>.
46
107
</para>
47
-
<itemizedlist>
48
-
<listitem>
49
-
<para>
50
-
<literal>salt</literal> - to manually provide a salt to use when hashing the password.
51
-
Note that this will override and prevent a salt from being automatically generated.
52
-
</para>
53
-
<para>
54
-
If omitted, a random salt will be generated by <function>password_hash</function> for
55
-
each password hashed. This is the intended mode of operation.
56
-
</para>
57
-
<warning>
58
-
<para>
59
-
The salt option has been deprecated as of PHP 7.0.0. It is now
60
-
preferred to simply use the salt that is generated by default.
61
-
</para>
62
-
</warning>
63
-
</listitem>
64
-
<listitem>
65
-
<para>
66
-
<literal>cost</literal> - which denotes the algorithmic cost that should be used.
67
-
Examples of these values can be found on the <function>crypt</function> page.
68
-
</para>
69
-
<para>
70
-
If omitted, a default value of <literal>10</literal> will be used. This is a good
71
-
baseline cost, but you may want to consider increasing it depending on your hardware.
72
-
</para>
73
-
</listitem>
74
-
</itemizedlist>
108
+
</listitem>
109
+
<listitem>
110
+
<para>
111
+
<literal>threads</literal> (<type>int</type>) - Number of threads to use for computing
112
+
the Argon2 hash. Defaults to <constant>PASSWORD_ARGON2_DEFAULT_THREADS</constant>.
113
+
</para>
114
+
<warning>
115
+
<para>
116
+
Only available when PHP uses libargon2, not with libsodium implementation.
117
+
</para>
118
+
</warning>
75
119
</listitem>
76
120
</itemizedlist>
77
121
</para>
...
...
@@ -91,7 +135,7 @@
91
135
Using the <constant>PASSWORD_BCRYPT</constant> as the
92
136
algorithm, will result
93
137
in the <parameter>password</parameter> parameter being truncated to a
94
-
maximum length of 72 characters.
138
+
maximum length of 72 bytes.
95
139
</para>
96
140
</caution>
97
141
</listitem>
...
...
@@ -122,7 +166,7 @@
122
166
<refsect1 role="returnvalues">
123
167
&reftitle.returnvalues;
124
168
<para>
125
-
Returns the hashed password, &return.falseforfailure;.
169
+
Returns the hashed password.
126
170
</para>
127
171
<para>
128
172
The used algorithm, cost and salt are returned as part of the hash. Therefore,
...
...
@@ -132,6 +176,64 @@
132
176
</para>
133
177
</refsect1>
134
178

179
+
<refsect1 role="changelog">
180
+
&reftitle.changelog;
181
+
<para>
182
+
<informaltable>
183
+
<tgroup cols="2">
184
+
<thead>
185
+
<row>
186
+
<entry>&Version;</entry>
187
+
<entry>&Description;</entry>
188
+
</row>
189
+
</thead>
190
+
<tbody>
191
+
<row>
192
+
<entry>8.0.0</entry>
193
+
<entry>
194
+
<function>password_hash</function> no longer returns &false; on failure, instead a
195
+
<classname>ValueError</classname> will be thrown if the password hashing algorithm
196
+
is not valid, or an <classname>Error</classname> if the password hashing failed
197
+
for an unknown error.
198
+
</entry>
199
+
</row>
200
+
<row>
201
+
<entry>8.0.0</entry>
202
+
<entry>
203
+
The <parameter>algo</parameter> parameter is nullable now.
204
+
</entry>
205
+
</row>
206
+
<row>
207
+
<entry>7.4.0</entry>
208
+
<entry>
209
+
The <parameter>algo</parameter> parameter expects a &string; now, but still accepts
210
+
&integer;s for backward compatibility.
211
+
</entry>
212
+
</row>
213
+
<row>
214
+
<entry>7.4.0</entry>
215
+
<entry>
216
+
The sodium extension provides an alternative implementation for Argon2 passwords.
217
+
</entry>
218
+
</row>
219
+
<row>
220
+
<entry>7.3.0</entry>
221
+
<entry>
222
+
Support for Argon2id passwords using <constant>PASSWORD_ARGON2ID</constant> was added.
223
+
</entry>
224
+
</row>
225
+
<row>
226
+
<entry>7.2.0</entry>
227
+
<entry>
228
+
Support for Argon2i passwords using <constant>PASSWORD_ARGON2I</constant> was added.
229
+
</entry>
230
+
</row>
231
+
</tbody>
232
+
</tgroup>
233
+
</informaltable>
234
+
</para>
235
+
</refsect1>
236
+

135
237
<refsect1 role="examples">
136
238
&reftitle.examples;
137
239
<para>
...
...
@@ -147,7 +249,7 @@
147
249
* Beware that DEFAULT may change over time, so you would want to prepare
148
250
* By allowing your storage to expand past 60 characters (255 would be good)
149
251
*/
150
-
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
252
+
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
151
253
?>
152
254
]]>
153
255
</programlisting>
...
...
@@ -172,7 +274,7 @@ $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
172
274
$options = [
173
275
'cost' => 12,
174
276
];
175
-
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
277
+
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
176
278
?>
177
279
]]>
178
280
</programlisting>
...
...
@@ -184,66 +286,55 @@ $2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K
184
286
</screen>
185
287
</example>
186
288
</para>
187
-
188
289
<para>
189
290
<example>
190
-
<title><function>password_hash</function> example setting salt manually</title>
291
+
<title><function>password_hash</function> example finding a good cost</title>
191
292
<programlisting role="php">
192
293
<![CDATA[
193
294
<?php
194
295
/**
195
-
* Note that the salt here is randomly generated.
196
-
* Never use a static salt or one that is not randomly generated.
197
-
*
198
-
* For the VAST majority of use-cases, let password_hash generate the salt randomly for you
296
+
* This code will benchmark your server to determine how high of a cost you can
297
+
* afford. You want to set the highest cost that you can without slowing down
298
+
* you server too much. 10 is a good baseline, and more is good if your servers
299
+
* are fast enough. The code below aims for ≤ 350 milliseconds stretching time,
300
+
* which is an appropriate delay for systems handling interactive logins.
199
301
*/
200
-
$options = [
201
-
'cost' => 11,
202
-
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
203
-
];
204
-
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
302
+
$timeTarget = 0.350; // 350 milliseconds
303
+

304
+
$cost = 10;
305
+
do {
306
+
$cost++;
307
+
$start = microtime(true);
308
+
password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
309
+
$end = microtime(true);
310
+
} while (($end - $start) < $timeTarget);
311
+

312
+
echo "Appropriate Cost Found: " . $cost;
205
313
?>
206
314
]]>
207
315
</programlisting>
208
316
&example.outputs.similar;
209
317
<screen>
210
318
<![CDATA[
211
-
$2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F.
319
+
Appropriate Cost Found: 12
212
320
]]>
213
321
</screen>
214
322
</example>
215
323
</para>
216
324
<para>
217
325
<example>
218
-
<title><function>password_hash</function> example finding a good cost</title>
326
+
<title><function>password_hash</function> example using Argon2i</title>
219
327
<programlisting role="php">
220
328
<![CDATA[
221
329
<?php
222
-
/**
223
-
* This code will benchmark your server to determine how high of a cost you can
224
-
* afford. You want to set the highest cost that you can without slowing down
225
-
* you server too much. 8-10 is a good baseline, and more is good if your servers
226
-
* are fast enough. The code below aims for ≤ 50 milliseconds stretching time,
227
-
* which is a good baseline for systems handling interactive logins.
228
-
*/
229
-
$timeTarget = 0.05; // 50 milliseconds
230
-

231
-
$cost = 8;
232
-
do {
233
-
$cost++;
234
-
$start = microtime(true);
235
-
password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
236
-
$end = microtime(true);
237
-
} while (($end - $start) < $timeTarget);
238
-

239
-
echo "Appropriate Cost Found: " . $cost . "\n";
330
+
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
240
331
?>
241
332
]]>
242
333
</programlisting>
243
334
&example.outputs.similar;
244
335
<screen>
245
336
<![CDATA[
246
-
Appropriate Cost Found: 10
337
+
Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
247
338
]]>
248
339
</screen>
249
340
</example>
...
...
@@ -261,13 +352,13 @@ Appropriate Cost Found: 10
261
352
<para>
262
353
As noted above, providing the <literal>salt</literal> option in PHP 7.0
263
354
will generate a deprecation warning. Support for providing a salt manually
264
-
may be removed in a future PHP release.
355
+
has been removed in PHP 8.0.
265
356
</para>
266
357
</caution>
267
358
<note>
268
359
<para>
269
360
It is recommended that you test this function on your servers, and adjust the cost parameter
270
-
so that execution of the function takes less than 100 milliseconds on interactive systems.
361
+
so that execution of the function takes less than 350 milliseconds on interactive systems.
271
362
The script in the above example will help you choose a good cost value for your hardware.
272
363
</para>
273
364
</note>
...
...
@@ -305,8 +396,9 @@ Appropriate Cost Found: 10
305
396
<para>
306
397
<simplelist>
307
398
<member><function>password_verify</function></member>
399
+
<member><function>password_needs_rehash</function></member>
308
400
<member><function>crypt</function></member>
309
-
<member><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&url.password.compat;">userland implementation</link></member>
401
+
<member><function>sodium_crypto_pwhash_str</function></member>
310
402
</simplelist>
311
403
</para>
312
404
</refsect1>
313
405