1String::Compare::ConstaUnsteTrimCeo(n3t)ributed Perl DocSutmreinntga:t:iCoonmpare::ConstantTime(3)
2
3
4
6 String::Compare::ConstantTime - Timing side-channel protected string
7 compare
8
10 use String::Compare::ConstantTime;
11
12 if (String::Compare::ConstantTime::equals($secret_data, $user_supplied_data)) {
13 ## The strings are eq
14 }
15
16 An example with HMACs:
17
18 use String::Compare::ConstantTime;
19 use Digest::HMAC_SHA1; ## or whatever
20
21 my $hmac_ctx = Digest::HMAC_SHA1->new($key);
22 $hmac_ctx->add($data);
23 my $digest = $hmac_ctx->digest;
24
25 if (String::Compare::ConstantTime::equals($digest, $candidate_digest)) {
26 ## The candidate digest is valid
27 }
28
30 This module provides one function, "equals" (not exported by default).
31
32 You should pass this function two strings of the same length. Just like
33 perl's "eq", it will return true if they are string-wise identical and
34 false otherwise. However, comparing any two differing strings of the
35 same length will take a fixed amount of time. If the lengths of the
36 strings are different, "equals" will return false right away.
37
38 NOTE: This does byte-wise comparison of the underlying string storage,
39 meaning that comparing strings with non-ASCII data with different
40 states of the internal UTF-8 flag is not reliable. You should always
41 encode your data to bytes before comparing.
42
44 Some programs take different amounts of time to run depending on the
45 input values provided to them. Untrusted parties can sometimes learn
46 information you might not want them to know by measuring this time.
47 This is called a "timing side-channel".
48
49 Most routines that compare strings (like perl's "eq" and "cmp" and C's
50 "strcmp" and "memcmp") start scanning from the start of the strings and
51 terminate as soon as they determine the strings won't match. This is
52 good for efficiency but bad because it opens a timing side-channel. If
53 one of the strings being compared is a secret and the other is
54 controlled by some untrusted party, it is sometimes possible for this
55 untrusted party to learn the secret using a timing side-channel.
56
57 If the lengths of the strings are different, because "equals" returns
58 false right away the size of the secret string may be leaked (but not
59 its contents).
60
62 HMACs are "Message Authentication Codes" built on top of cryptographic
63 hashes. The HMAC algorithm produces digests that are included along
64 with a message in order to verify that whoever created the message
65 knows a particular secret password, and that this message hasn't been
66 tampered with since.
67
68 To verify a candidate digest included with a message, you re-compute
69 the digest using the message and the secret password. If this computed
70 digest is is the same as the candidate digest then the message is
71 considered authenticated.
72
73 A common side-channel attack against services that verify unlimited
74 numbers of messages automatically is to create a forged message and
75 then just send some random junk as the candidate digest. Continue
76 sending this message and junk digests that vary by the first character.
77 Repeat many times. If you find a particular digest that statistically
78 takes a longer time to be rejected than the other digests, it is
79 probably because this particular digest has the first character correct
80 and the service's final string comparison is running slightly longer.
81
82 At this point, you keep this first character fixed and start varying
83 the second character until it is solved. Repeat until all the
84 characters are solved or until the amount of remaining possibilities
85 are so small you can brute force it. At this point, your candidate
86 digest is considered valid and you have forged a message.
87
88 Note that this particular attack doesn't allow the attacker to recover
89 the secret input key to the HMAC but nevertheless can produce a valid
90 digest for any message given enough time because the service that
91 validates the HMAC is acting as an "oracle".
92
93 NOTE: Although this module protects against a common attack against
94 applications that store state in browser cookies, it is in no way an
95 endorsement of this practise.
96
98 Pin tumbler locks are susceptible to being picked in a similar way to
99 an attacker forging HMAC digests using a timing side-channel.
100
101 The traditional way to pick cheap pin tumbler locks is to apply torque
102 to the lock cylinder so that the pins are pressed against the cylinder.
103 However, because of slight manufacturing discrepancies one particular
104 pin will be the widest by a slight margin and will be pressed against
105 the cylinder tighter than the others (the cheaper the lock, the higher
106 the manufacturing tolerances). The attacker lifts this pin until the
107 cylinder gives a little bit, indicating that this pin has been solved
108 and the next widest pin is now the one being pressed against the
109 cylinder the tightest. This process is repeated until all the pins are
110 solved and the lock opens.
111
112 Just like an attacker trying to solve HMAC digests can work on one
113 character at a time, a lock pick can work on each pin in isolation. To
114 protect against this, quality locks force all pins to be fixed into
115 place before the cylinder rotation can be attempted, just as secure
116 HMAC verifiers force attackers to guess the entire digest on each
117 attempt.
118
120 The String-Compare-ConstantTime github repo
121 <https://github.com/hoytech/String-Compare-ConstantTime>
122
123 Authen::Passphrase has a good section on side-channel cryptanalysis
124 such as it pertains to password storage (mostly, it doesn't).
125
126 The famous TENEX password bug
127 <https://web.archive.org/web/20150913074712/http://www.meadhbh.org/services/passwords>
128
129 Example of a timing bug <http://rdist.root.org/2009/05/28/timing-
130 attack-in-google-keyczar-library/>
131
132 QSCAN <http://hcsw.org/nmap/QSCAN>
133
134 Practical limits of the timing side channel
135 <http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf>
136
137 NaCl: Crypto library designed to prevent side channel attacks
138 <http://nacl.cr.yp.to/>
139
141 Doug Hoyte, "<doug@hcsw.org>"
142
144 Copyright 2012-2018 Doug Hoyte.
145
146 Contributions from Paul Cochrane.
147
148 This module is licensed under the same terms as perl itself.
149
150
151
152perl v5.36.0 2023-01-20 String::Compare::ConstantTime(3)