-
Notifications
You must be signed in to change notification settings - Fork 109
Expand file tree
/
Copy pathpassword-hash.xml
More file actions
406 lines (394 loc) · 12.5 KB
/
password-hash.xml
File metadata and controls
406 lines (394 loc) · 12.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 5003a6ea92eb50ac92121782eedfc5ad3fe9d061 Maintainer: daijie Status: ready -->
<!-- CREDITS: Luffy, mowangjuanzi -->
<refentry xml:id="function.password-hash" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>password_hash</refname>
<refpurpose>创建密码的散列(hash)</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<type>string</type><methodname>password_hash</methodname>
<methodparam><modifier role="attribute">#[\SensitiveParameter]</modifier><type>string</type><parameter>password</parameter></methodparam>
<methodparam><type class="union"><type>string</type><type>int</type><type>null</type></type><parameter>algo</parameter></methodparam>
<methodparam choice="opt"><type>array</type><parameter>options</parameter><initializer>[]</initializer></methodparam>
</methodsynopsis>
<para>
<function>password_hash</function> 使用足够强度的单向散列算法创建密码的散列(hash)。
</para>
<simpara>
当前支持的算法:
</simpara>
<para>
<itemizedlist>
<listitem>
<simpara>
<constant>PASSWORD_DEFAULT</constant> - 使用 bcrypt 算法 (PHP 5.5.0 默认)。
注意,该常量会随着 PHP 加入更新更高强度的算法而改变。
所以,使用此常量生成结果的长度将在未来有变化。
因此,数据库里储存结果的列可超过60个字节(最好是255个字节)。
</simpara>
</listitem>
<listitem>
<simpara>
<constant>PASSWORD_BCRYPT</constant> - 使用 bcrypt 算法创建散列。
这将使用 <literal>$2y$</literal> 标识生成标准的 <function>crypt</function> 兼容散列。
</simpara>
</listitem>
<listitem>
<simpara>
<constant>PASSWORD_ARGON2I</constant> - 使用 Argon2i 散列算法创建散列。
只有在 PHP 编译时加入 Argon2 支持时才能使用该算法。
</simpara>
</listitem>
<listitem>
<simpara>
<constant>PASSWORD_ARGON2ID</constant> - 使用 Argon2id 散列算法创建散列。
只有在 PHP 编译时加入 Argon2 支持时才能使用该算法。
</simpara>
</listitem>
</itemizedlist>
</para>
<simpara>
<constant>PASSWORD_BCRYPT</constant> 支持的选项:
</simpara>
<para>
<itemizedlist>
<listitem>
<para>
<literal>salt</literal>(<type>string</type>) - 手动提供散列密码的盐值(salt)。这将避免自动生成盐值(salt)。
</para>
<para>
省略此值后,<function>password_hash</function> 会为每个密码散列自动生成随机的盐值。这种操作是有意的模式。
</para>
<warning>
<para>
盐值(salt)选项已废弃(deprecated)。
现在最好仅选择使用默认产生的盐值。
从 PHP 8.0.0 起,明确指定的 salt 值会被忽略。
</para>
</warning>
</listitem>
<listitem>
<para>
<literal>cost</literal> (<type>int</type>) - 代表算法使用的 cost。<function>crypt</function> 页面上有 cost 值的示例。
</para>
<para>
省略时,默认值是 <literal>12</literal>。
这个 cost 是个不错的底线,但应根据使用的硬件进行调整。
</para>
</listitem>
</itemizedlist>
</para>
<simpara>
<constant>PASSWORD_ARGON2I</constant> 和 <constant>PASSWORD_ARGON2ID</constant> 支持的选项:
</simpara>
<para>
<itemizedlist>
<listitem>
<para>
<literal>memory_cost</literal> (<type>int</type>) - 计算 Argon2 散列时的最大内存(单位:KB)。默认值: <constant>PASSWORD_ARGON2_DEFAULT_MEMORY_COST</constant>。
</para>
</listitem>
<listitem>
<para>
<literal>time_cost</literal> (<type>int</type>) - 计算 Argon2 散列时最多的时间。默认值: <constant>PASSWORD_ARGON2_DEFAULT_TIME_COST</constant>。
</para>
</listitem>
<listitem>
<para>
<literal>threads</literal> (<type>int</type>) - 计算 Argon2 散列时最多的线程数。默认值: <constant>PASSWORD_ARGON2_DEFAULT_THREADS</constant>。
</para>
<warning>
<para>
只有在 PHP 使用 libargon2 时可用;如果是 libsodium 的实现,则无法使用。
</para>
</warning>
</listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<variablelist>
<varlistentry>
<term><parameter>password</parameter></term>
<listitem>
<para>
&password.parameter.password;
</para>
<caution>
<para>
使用 <constant>PASSWORD_BCRYPT</constant> 做算法,将使 <parameter>password</parameter> 参数最长为72个字节,超过会被截断。
</para>
</caution>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>algo</parameter></term>
<listitem>
<para>
&password.parameter.algo;
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>options</parameter></term>
<listitem>
<para>
&password.parameter.options;
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
返回散列后的密码。
</para>
<para>
使用的算法、cost 和盐值作为散列的一部分返回。所以验证散列值的所有信息都已经包含在内。
这使 <function>password_verify</function> 函数验证的时候,不需要额外储存盐值或者算法的信息。
</para>
</refsect1>
<refsect1 role="changelog">
&reftitle.changelog;
<para>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>&Version;</entry>
<entry>&Description;</entry>
</row>
</thead>
<tbody>
<row>
<entry>8.4.0</entry>
<entry>
<constant>PASSWORD_BCRYPT</constant> 算法的 <literal>cost</literal> 选项的默认值从
<literal>10</literal> 增加到 <literal>12</literal>。
</entry>
</row>
<row>
<entry>8.3.0</entry>
<entry>
当由于盐值生成失败而抛出 <exceptionname>ValueError</exceptionname> 时,
<function>password_hash</function> 现在会将底层的
<exceptionname>Random\RandomException</exceptionname> 作为
<property>Exception::$previous</property> 异常。
</entry>
</row>
<row>
<entry>8.0.0</entry>
<entry>
失败时 <function>password_hash</function> 不再返回 &false;,如果密码散列算法无效,则会抛出
<classname>ValueError</classname>,如果密码散列因未知错误失败,则会抛出 <classname>Error</classname>。
</entry>
</row>
<row>
<entry>8.0.0</entry>
<entry>
参数 <parameter>algo</parameter> 可以为 null。
</entry>
</row>
<row>
<entry>7.4.0</entry>
<entry>
现在 <parameter>algo</parameter> 参数可支持 &string; 类型,但为了向后兼容也支持
&integer; 类型。
</entry>
</row>
<row>
<entry>7.4.0</entry>
<entry>
扩展 sodium 提供了 Argon2 密码的替代实现。
</entry>
</row>
<row>
<entry>7.3.0</entry>
<entry>
增加 <constant>PASSWORD_ARGON2ID</constant>,支持 Argon2id 密码算法。
</entry>
</row>
<row>
<entry>7.2.0</entry>
<entry>
增加 <constant>PASSWORD_ARGON2I</constant>,支持 Argon2i 密码算法。
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title><function>password_hash</function> 示例</title>
<programlisting role="php">
<![CDATA[
<?php
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
$2y$12$4Umg0rCJwMswRw/l.SwHvuQV01coP0eWmGzd61QH2RvAOMANUBGC.
]]>
</screen>
</example>
</para>
<para>
<example>
<title><function>password_hash</function> 手动设置 cost 的示例</title>
<programlisting role="php">
<![CDATA[
<?php
$options = [
// Increase the bcrypt cost from 12 to 13.
'cost' => 13,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
$2y$13$xeDfQumlmdm0Sco.4qmH1OGfUUmOcuRmfae0dPJhjX1Bq0yYhqbNi
]]>
</screen>
</example>
</para>
<para>
<example>
<title>寻找最佳 cost 的 <function>password_hash</function> 示例</title>
<simpara>
该代码将会基准测试机器,来确定可以使用多高的 cost 而不会影响用户体验。
建议设置最高的 cost,前提是不会减慢机器需要执行的其他操作。
11 是一个不错的基线,如果机器足够快,更多的 cost 更好。
下面的代码目标是 ≤ 350 毫秒的拉伸时间(stretching time),这是处理交互式登录的系统的适当延迟。
</simpara>
<programlisting role="php">
<![CDATA[
<?php
$timeTarget = 0.350; // 350 毫秒(milliseconds)
$cost = 11;
do {
$cost++;
$start = microtime(true);
password_hash("test", PASSWORD_BCRYPT, ["cost" => $cost]);
$end = microtime(true);
} while (($end - $start) < $timeTarget);
echo "Appropriate Cost Found: " . $cost - 1;
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Appropriate Cost Found: 13
]]>
</screen>
</example>
</para>
<para>
<example>
<title>使用 Argon2i 的 <function>password_hash</function> 示例</title>
<programlisting role="php">
<![CDATA[
<?php
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
]]>
</screen>
</example>
</para>
</refsect1>
<refsect1 role="notes">
&reftitle.notes;
<caution>
<para>
强烈建议不要为此函数提供显式的盐值(salt)。
如果没有指定盐值(salt),将自动创建一个安全的盐值(salt)。
</para>
<para>
提供 <literal>salt</literal> 选项在 PHP 7.0.0 中会生成一个弃用(deprecated)警告。
在 PHP 8.0.0 中,显式提供盐值(salt)的支持已被删除。
</para>
</caution>
<note>
<para>
建议在使用的机器上测试此函数,调整 cost 参数,使得函数执行时间小于 350 毫秒,适合交互式登录。
上面示例中的脚本将帮助选择适合给定机器的 bcrypt cost。
</para>
</note>
<note>
<simpara>
这个函数更新支持的算法时(或修改默认算法),必定会遵守以下规则:
</simpara>
<para>
<itemizedlist>
<listitem>
<simpara>
任何内核中的新算法必须在经历一次 PHP 完整发行才能成为默认算法。
比如,在 PHP 7.5.5 中添加的新算法,在 PHP 7.7 之前不能成为默认算法
(由于 7.6 是第一个完整发行版)。
但如果是在 7.6.0 里添加的不同算法,在 7.7.0 里也可以成为默认算法。
</simpara>
</listitem>
<listitem>
<simpara>
仅仅允许在完整发行版中修改默认算法(比如 7.3.0, 8.0.0,等等),不能是在修订版。
唯一的例外是:在当前默认算法里发现了紧急的安全威胁。
</simpara>
</listitem>
</itemizedlist>
</para>
</note>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><function>password_verify</function></member>
<member><function>password_needs_rehash</function></member>
<member><function>crypt</function></member>
<member><function>sodium_crypto_pwhash_str</function></member>
</simplelist>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->