reference/password/functions/password-hash.xml
5003a6ea92eb50ac92121782eedfc5ad3fe9d061
5003a6ea92eb50ac92121782eedfc5ad3fe9d061
...
...
@@ -1,6 +1,5 @@
1
-
<?xml version="1.0" encoding="utf-8"?>
1
+
<?xml version="1.0" encoding="utf-8"?>
2
2
<!-- $Revision$ -->
3
-
4
3
<refentry xml:id="function.password-hash" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
5
4
<refnamediv>
6
5
<refname>password_hash</refname>
...
...
@@ -11,15 +10,13 @@
11
10
&reftitle.description;
12
11
<methodsynopsis>
13
12
<type>string</type><methodname>password_hash</methodname>
14
-
<methodparam><type>string</type><parameter>password</parameter></methodparam>
15
-
<methodparam><type>int</type><parameter>algo</parameter></methodparam>
16
-
<methodparam choice="opt"><type>array</type><parameter>options</parameter></methodparam>
13
+
<methodparam><modifier role="attribute">#[\SensitiveParameter]</modifier><type>string</type><parameter>password</parameter></methodparam>
14
+
<methodparam><type class="union"><type>string</type><type>int</type><type>null</type></type><parameter>algo</parameter></methodparam>
15
+
<methodparam choice="opt"><type>array</type><parameter>options</parameter><initializer>[]</initializer></methodparam>
17
16
</methodsynopsis>
18
17
<para>
19
18
<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>.
19
+
algorithm.
23
20
</para>
24
21
<simpara>
25
22
The following algorithms are currently supported:
...
...
@@ -32,19 +29,26 @@
32
29
Note that this constant is designed to change over time as new and stronger algorithms are added
33
30
to PHP. For that reason, the length of the result from using this identifier can change over
34
31
time. Therefore, it is recommended to store the result in a database column that can expand
35
-
beyond 60 characters (255 characters would be a good choice).
32
+
beyond 60 bytes (255 bytes would be a good choice).
36
33
</simpara>
37
34
</listitem>
38
35
<listitem>
39
36
<simpara>
40
-
<constant>PASSWORD_BCRYPT</constant> - Use the <constant>CRYPT_BLOWFISH</constant> algorithm to
37
+
<constant>PASSWORD_BCRYPT</constant> - Use the bcrypt algorithm to
41
38
create the hash. This will produce a standard <function>crypt</function> compatible hash using
42
-
the "$2y$" identifier. The result will always be a 60 character string, &return.falseforfailure;.
39
+
the <literal>$2y$</literal> identifier.
43
40
</simpara>
44
41
</listitem>
45
42
<listitem>
46
43
<simpara>
47
-
<constant>PASSWORD_ARGON2I</constant> - Use the Argon2 hashing algorithm to create the hash.
44
+
<constant>PASSWORD_ARGON2I</constant> - Use the Argon2i hashing algorithm to create the hash.
45
+
This algorithm is only available if PHP has been compiled with Argon2 support.
46
+
</simpara>
47
+
</listitem>
48
+
<listitem>
49
+
<simpara>
50
+
<constant>PASSWORD_ARGON2ID</constant> - Use the Argon2id hashing algorithm to create the hash.
51
+
This algorithm is only available if PHP has been compiled with Argon2 support.
48
52
</simpara>
49
53
</listitem>
50
54
</itemizedlist>
...
...
@@ -65,45 +69,52 @@
65
69
</para>
66
70
<warning>
67
71
<para>
68
-
The salt option has been deprecated as of PHP 7.0.0. It is now
72
+
The salt option is deprecated. It is now
69
73
preferred to simply use the salt that is generated by default.
74
+
As of PHP 8.0.0, an explicitly given salt is ignored.
70
75
</para>
71
76
</warning>
72
77
</listitem>
73
78
<listitem>
74
79
<para>
75
-
<literal>cost</literal> (<type>integer</type>) - which denotes the algorithmic cost that should be used.
80
+
<literal>cost</literal> (<type>int</type>) - which denotes the algorithmic cost that should be used.
76
81
Examples of these values can be found on the <function>crypt</function> page.
77
82
</para>
78
83
<para>
79
-
If omitted, a default value of <literal>10</literal> will be used. This is a good
80
-
baseline cost, but you may want to consider increasing it depending on your hardware.
84
+
If omitted, a default value of <literal>12</literal> will be used. This is a good
85
+
baseline cost, but it should be adjusted depending on hardware used.
81
86
</para>
82
87
</listitem>
83
88
</itemizedlist>
84
89
</para>
85
90
<simpara>
86
-
Supported options for <constant>PASSWORD_ARGON2I</constant>:
91
+
Supported options for <constant>PASSWORD_ARGON2I</constant>
92
+
and <constant>PASSWORD_ARGON2ID</constant>:
87
93
</simpara>
88
94
<para>
89
95
<itemizedlist>
90
96
<listitem>
91
97
<para>
92
-
<literal>memory_cost</literal> (<type>integer</type>) - Maximum memory (in bytes) that may
98
+
<literal>memory_cost</literal> (<type>int</type>) - Maximum memory (in kibibytes) that may
93
99
be used to compute the Argon2 hash. Defaults to <constant>PASSWORD_ARGON2_DEFAULT_MEMORY_COST</constant>.
94
100
</para>
95
101
</listitem>
96
102
<listitem>
97
103
<para>
98
-
<literal>time_cost</literal> (<type>integer</type>) - Maximum amount of time it may
104
+
<literal>time_cost</literal> (<type>int</type>) - Maximum amount of time it may
99
105
take to compute the Argon2 hash. Defaults to <constant>PASSWORD_ARGON2_DEFAULT_TIME_COST</constant>.
100
106
</para>
101
107
</listitem>
102
108
<listitem>
103
109
<para>
104
-
<literal>threads</literal> (<type>integer</type>) - Number of threads to use for computing
110
+
<literal>threads</literal> (<type>int</type>) - Number of threads to use for computing
105
111
the Argon2 hash. Defaults to <constant>PASSWORD_ARGON2_DEFAULT_THREADS</constant>.
106
112
</para>
113
+
<warning>
114
+
<para>
115
+
Only available when PHP uses libargon2, not with libsodium implementation.
116
+
</para>
117
+
</warning>
107
118
</listitem>
108
119
</itemizedlist>
109
120
</para>
...
...
@@ -123,7 +134,7 @@
123
134
Using the <constant>PASSWORD_BCRYPT</constant> as the
124
135
algorithm, will result
125
136
in the <parameter>password</parameter> parameter being truncated to a
126
-
maximum length of 72 characters.
137
+
maximum length of 72 bytes.
127
138
</para>
128
139
</caution>
129
140
</listitem>
...
...
@@ -142,10 +153,6 @@
142
153
<para>
143
154
&password.parameter.options;
144
155
</para>
145
-
<para>
146
-
If omitted, a random salt will be created and the default cost will be
147
-
used.
148
-
</para>
149
156
</listitem>
150
157
</varlistentry>
151
158
</variablelist>
...
...
@@ -154,7 +161,7 @@
154
161
<refsect1 role="returnvalues">
155
162
&reftitle.returnvalues;
156
163
<para>
157
-
Returns the hashed password, &return.falseforfailure;.
164
+
Returns the hashed password.
158
165
</para>
159
166
<para>
160
167
The used algorithm, cost and salt are returned as part of the hash. Therefore,
...
...
@@ -164,6 +171,82 @@
164
171
</para>
165
172
</refsect1>
166
173
174
+
<refsect1 role="changelog">
175
+
&reftitle.changelog;
176
+
<para>
177
+
<informaltable>
178
+
<tgroup cols="2">
179
+
<thead>
180
+
<row>
181
+
<entry>&Version;</entry>
182
+
<entry>&Description;</entry>
183
+
</row>
184
+
</thead>
185
+
<tbody>
186
+
<row>
187
+
<entry>8.4.0</entry>
188
+
<entry>
189
+
The default value of the <literal>cost</literal> option of the
190
+
<constant>PASSWORD_BCRYPT</constant> algorithm was increased from
191
+
<literal>10</literal> to <literal>12</literal>.
192
+
</entry>
193
+
</row>
194
+
<row>
195
+
<entry>8.3.0</entry>
196
+
<entry>
197
+
<function>password_hash</function> now sets the underlying
198
+
<exceptionname>Random\RandomException</exceptionname> as the
199
+
<property>Exception::$previous</property> exception when a
200
+
<exceptionname>ValueError</exceptionname> is thrown due to a failure
201
+
in the salt generation.
202
+
</entry>
203
+
</row>
204
+
<row>
205
+
<entry>8.0.0</entry>
206
+
<entry>
207
+
<function>password_hash</function> no longer returns &false; on failure, instead a
208
+
<classname>ValueError</classname> will be thrown if the password hashing algorithm
209
+
is not valid, or an <classname>Error</classname> if the password hashing failed
210
+
for an unknown error.
211
+
</entry>
212
+
</row>
213
+
<row>
214
+
<entry>8.0.0</entry>
215
+
<entry>
216
+
The <parameter>algo</parameter> parameter is nullable now.
217
+
</entry>
218
+
</row>
219
+
<row>
220
+
<entry>7.4.0</entry>
221
+
<entry>
222
+
The <parameter>algo</parameter> parameter expects a &string; now, but still accepts
223
+
&integer;s for backward compatibility.
224
+
</entry>
225
+
</row>
226
+
<row>
227
+
<entry>7.4.0</entry>
228
+
<entry>
229
+
The sodium extension provides an alternative implementation for Argon2 passwords.
230
+
</entry>
231
+
</row>
232
+
<row>
233
+
<entry>7.3.0</entry>
234
+
<entry>
235
+
Support for Argon2id passwords using <constant>PASSWORD_ARGON2ID</constant> was added.
236
+
</entry>
237
+
</row>
238
+
<row>
239
+
<entry>7.2.0</entry>
240
+
<entry>
241
+
Support for Argon2i passwords using <constant>PASSWORD_ARGON2I</constant> was added.
242
+
</entry>
243
+
</row>
244
+
</tbody>
245
+
</tgroup>
246
+
</informaltable>
247
+
</para>
248
+
</refsect1>
249
+
167
250
<refsect1 role="examples">
168
251
&reftitle.examples;
169
252
<para>
...
...
@@ -172,13 +255,6 @@
172
255
<programlisting role="php">
173
256
<![CDATA[
174
257
<?php
175
-
/**
176
-
* We just want to hash our password using the current DEFAULT algorithm.
177
-
* This is presently BCRYPT, and will produce a 60 character result.
178
-
*
179
-
* Beware that DEFAULT may change over time, so you would want to prepare
180
-
* By allowing your storage to expand past 60 characters (255 would be good)
181
-
*/
182
258
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
183
259
?>
184
260
]]>
...
...
@@ -186,7 +262,7 @@ echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
186
262
&example.outputs.similar;
187
263
<screen>
188
264
<![CDATA[
189
-
$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
265
+
$2y$12$4Umg0rCJwMswRw/l.SwHvuQV01coP0eWmGzd61QH2RvAOMANUBGC.
190
266
]]>
191
267
</screen>
192
268
</example>
...
...
@@ -197,41 +273,9 @@ $2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
197
273
<programlisting role="php">
198
274
<![CDATA[
199
275
<?php
200
-
/**
201
-
* In this case, we want to increase the default cost for BCRYPT to 12.
202
-
* Note that we also switched to BCRYPT, which will always be 60 characters.
203
-
*/
204
-
$options = [
205
-
'cost' => 12,
206
-
];
207
-
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
208
-
?>
209
-
]]>
210
-
</programlisting>
211
-
&example.outputs.similar;
212
-
<screen>
213
-
<![CDATA[
214
-
$2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K
215
-
]]>
216
-
</screen>
217
-
</example>
218
-
</para>
219
-
220
-
<para>
221
-
<example>
222
-
<title><function>password_hash</function> example setting salt manually</title>
223
-
<programlisting role="php">
224
-
<![CDATA[
225
-
<?php
226
-
/**
227
-
* Note that the salt here is randomly generated.
228
-
* Never use a static salt or one that is not randomly generated.
229
-
*
230
-
* For the VAST majority of use-cases, let password_hash generate the salt randomly for you
231
-
*/
232
276
$options = [
233
-
'cost' => 11,
234
-
'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
277
+
// Increase the bcrypt cost from 12 to 13.
278
+
'cost' => 13,
235
279
];
236
280
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
237
281
?>
...
...
@@ -240,7 +284,7 @@ echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
240
284
&example.outputs.similar;
241
285
<screen>
242
286
<![CDATA[
243
-
$2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F.
287
+
$2y$13$xeDfQumlmdm0Sco.4qmH1OGfUUmOcuRmfae0dPJhjX1Bq0yYhqbNi
244
288
]]>
245
289
</screen>
246
290
</example>
...
...
@@ -248,19 +292,20 @@ $2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F.
248
292
<para>
249
293
<example>
250
294
<title><function>password_hash</function> example finding a good cost</title>
295
+
<simpara>
296
+
This code will benchmark the machine to determine how high of a cost can be used
297
+
without deteriorating user experience. It is recommended to set the highest cost
298
+
that does not slow down other operations the machine needs to perform. 11 is a
299
+
good baseline, and more is better if the machine is fast enough. The code below
300
+
aims for ≤ 350 milliseconds stretching time, which is an appropriate delay for
301
+
systems handling interactive logins.
302
+
</simpara>
251
303
<programlisting role="php">
252
304
<![CDATA[
253
305
<?php
254
-
/**
255
-
* This code will benchmark your server to determine how high of a cost you can
256
-
* afford. You want to set the highest cost that you can without slowing down
257
-
* you server too much. 8-10 is a good baseline, and more is good if your servers
258
-
* are fast enough. The code below aims for ≤ 50 milliseconds stretching time,
259
-
* which is a good baseline for systems handling interactive logins.
260
-
*/
261
-
$timeTarget = 0.05; // 50 milliseconds
306
+
$timeTarget = 0.350; // 350 milliseconds
262
307
263
-
$cost = 8;
308
+
$cost = 11;
264
309
do {
265
310
$cost++;
266
311
$start = microtime(true);
...
...
@@ -268,32 +313,32 @@ do {
268
313
$end = microtime(true);
269
314
} while (($end - $start) < $timeTarget);
270
315
271
-
echo "Appropriate Cost Found: " . $cost;
316
+
echo "Appropriate Cost Found: " . $cost - 1;
272
317
?>
273
318
]]>
274
319
</programlisting>
275
320
&example.outputs.similar;
276
321
<screen>
277
322
<![CDATA[
278
-
Appropriate Cost Found: 10
323
+
Appropriate Cost Found: 13
279
324
]]>
280
325
</screen>
281
326
</example>
282
327
</para>
283
328
<para>
284
329
<example>
285
-
<title><function>password_hash</function> example using Argon2</title>
330
+
<title><function>password_hash</function> example using Argon2i</title>
286
331
<programlisting role="php">
287
332
<![CDATA[
288
333
<?php
289
-
echo 'Argon2 hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
334
+
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
290
335
?>
291
336
]]>
292
337
</programlisting>
293
338
&example.outputs.similar;
294
339
<screen>
295
340
<![CDATA[
296
-
Argon2 hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
341
+
Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
297
342
]]>
298
343
</screen>
299
344
</example>
...
...
@@ -304,21 +349,21 @@ Argon2 hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4
304
349
&reftitle.notes;
305
350
<caution>
306
351
<para>
307
-
It is strongly recommended that you do not generate your own salt for this
308
-
function. It will create a secure salt automatically for you if you do
309
-
not specify one.
352
+
It is strongly recommended not to provide an explicit salt for this function.
353
+
A secure salt will automatically be created if no salt is specified.
310
354
</para>
311
355
<para>
312
-
As noted above, providing the <literal>salt</literal> option in PHP 7.0
313
-
will generate a deprecation warning. Support for providing a salt manually
314
-
may be removed in a future PHP release.
356
+
As noted above, providing the <literal>salt</literal> option in PHP 7.0.0
357
+
will generate a deprecation warning. Support for providing a salt explicitly
358
+
has been removed in PHP 8.0.0.
315
359
</para>
316
360
</caution>
317
361
<note>
318
362
<para>
319
-
It is recommended that you test this function on your servers, and adjust the cost parameter
320
-
so that execution of the function takes less than 100 milliseconds on interactive systems.
321
-
The script in the above example will help you choose a good cost value for your hardware.
363
+
It is recommended to test this function on the machine used, adjusting the cost parameter(s)
364
+
so that execution of the function takes less than 350 milliseconds for interactive logins.
365
+
The script in the above example will help choosing an appropriate bcrypt cost for the given
366
+
machine.
322
367
</para>
323
368
</note>
324
369
<note>
...
...
@@ -350,43 +395,19 @@ Argon2 hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4
350
395
</note>
351
396
</refsect1>
352
397
353
-
<refsect1 role="changelog">
354
-
&reftitle.changelog;
355
-
<para>
356
-
<informaltable>
357
-
<tgroup cols="2">
358
-
<thead>
359
-
<row>
360
-
<entry>&Version;</entry>
361
-
<entry>&Description;</entry>
362
-
</row>
363
-
</thead>
364
-
<tbody>
365
-
<row>
366
-
<entry>7.2.0</entry>
367
-
<entry>
368
-
Support for Argon2 passwords using <constant>PASSWORD_ARGON2I</constant> was added.
369
-
</entry>
370
-
</row>
371
-
</tbody>
372
-
</tgroup>
373
-
</informaltable>
374
-
</para>
375
-
</refsect1>
376
-
377
398
<refsect1 role="seealso">
378
399
&reftitle.seealso;
379
400
<para>
380
401
<simplelist>
381
402
<member><function>password_verify</function></member>
403
+
<member><function>password_needs_rehash</function></member>
382
404
<member><function>crypt</function></member>
383
-
<member><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&url.password.compat;">userland implementation</link></member>
405
+
<member><function>sodium_crypto_pwhash_str</function></member>
384
406
</simplelist>
385
407
</para>
386
408
</refsect1>
387
409
388
410
</refentry>
389
-
390
411
<!-- Keep this comment at the end of the file
391
412
Local variables:
392
413
mode: sgml
393
414