reference/hash/functions/hash-equals.xml
472a8ae5cc4e91fcf8365760ba07787f61087aae
...
...
@@ -15,12 +15,22 @@
15
15
<methodparam><type>string</type><parameter>user_string</parameter></methodparam>
16
16
</methodsynopsis>
17
17
<para>
18
-
Compares two strings using the same time whether they're equal or not.
18
+
Checks whether two strings are equal without leaking information about the
19
+
contents of <parameter>known_string</parameter> via the execution time.
19
20
</para>
20
21
<para>
21
-
This function should be used to mitigate timing attacks; for instance,
22
-
when testing <function>crypt</function> password hashes.
22
+
This function can be used to mitigate timing attacks. Performing a regular
23
+
comparison with <code>===</code> will take more or less time to execute
24
+
depending on whether the two values are different or not and at which
25
+
position the first difference can be found, thus leaking information about
26
+
the contents of the secret <parameter>known_string</parameter>.
23
27
</para>
28
+
<caution>
29
+
<para>
30
+
It is important to provide the user-supplied string as the second
31
+
parameter, rather than the first.
32
+
</para>
33
+
</caution>
24
34
</refsect1>
25
35

26
36
<refsect1 role="parameters">
...
...
@@ -30,7 +40,7 @@
30
40
<term><parameter>known_string</parameter></term>
31
41
<listitem>
32
42
<para>
33
-
The <type>string</type> of known length to compare against
43
+
The known &string; that must be kept secret.
34
44
</para>
35
45
</listitem>
36
46
</varlistentry>
...
...
@@ -38,7 +48,7 @@
38
48
<term><parameter>user_string</parameter></term>
39
49
<listitem>
40
50
<para>
41
-
The user-supplied string
51
+
The user-supplied &string; to compare against.
42
52
</para>
43
53
</listitem>
44
54
</varlistentry>
...
...
@@ -52,14 +62,6 @@
52
62
</para>
53
63
</refsect1>
54
64

55
-
<refsect1 role="errors">
56
-
&reftitle.errors;
57
-
<para>
58
-
Emits an <constant>E_WARNING</constant> message when either of the
59
-
supplied parameters is not a string.
60
-
</para>
61
-
</refsect1>
62
-

63
65
<refsect1 role="examples">
64
66
&reftitle.examples;
65
67
<para>
...
...
@@ -68,20 +70,25 @@
68
70
<programlisting role="php">
69
71
<![CDATA[
70
72
<?php
71
-
$expected = crypt('12345', '$2a$07$usesomesillystringforsalt$');
72
-
$correct = crypt('12345', '$2a$07$usesomesillystringforsalt$');
73
-
$incorrect = crypt('apple', '$2a$07$usesomesillystringforsalt$');
73
+
$secretKey = '8uRhAeH89naXfFXKGOEj';
74
+

75
+
// Value and signature are provided by the user, e.g. within the URL
76
+
// and retrieved using $_GET.
77
+
$value = 'username=rasmuslerdorf';
78
+
$signature = '8c35009d3b50caf7f5d2c1e031842e6b7823a1bb781d33c5237cd27b57b5f327';
74
79

75
-
var_dump(hash_equals($expected, $correct));
76
-
var_dump(hash_equals($expected, $incorrect));
80
+
if (hash_equals(hash_hmac('sha256', $value, $secretKey), $signature)) {
81
+
echo "The value is correctly signed.", PHP_EOL;
82
+
} else {
83
+
echo "The value was tampered with.", PHP_EOL;
84
+
}
77
85
?>
78
86
]]>
79
87
</programlisting>
80
88
&example.outputs;
81
89
<screen>
82
90
<![CDATA[
83
-
bool(true)
84
-
bool(false)
91
+
The value is correctly signed.
85
92
]]>
86
93
</screen>
87
94
</example>
...
...
@@ -97,14 +104,16 @@ bool(false)
97
104
the length of the known string may be leaked in case of a timing attack.
98
105
</para>
99
106
</note>
100
-
<note>
101
-
<para>
102
-
It is important to provide the user-supplied string as the second
103
-
parameter, rather than the first.
104
-
</para>
105
-
</note>
106
107
</refsect1>
107
108

109
+
<refsect1 role="seealso">
110
+
&reftitle.seealso;
111
+
<para>
112
+
<simplelist>
113
+
<member><function>hash_hmac</function></member>
114
+
</simplelist>
115
+
</para>
116
+
</refsect1>
108
117
</refentry>
109
118

110
119
<!-- Keep this comment at the end of the file
111
120