Skip to content

Commit 8a69b7b

Browse files
Added NotConstantTimeCryptoComparison.qhelp and examples
1 parent 67579dd commit 8a69b7b

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
4+
<overview>
5+
<p>
6+
When comparing results of cryptographic operations, such as MAC or cryptographic hash,
7+
a constant time algorithm should be used. In other words, the comparison time should not depend on
8+
the content of the input. Otherwise, an attacker may be able to implement a timing attack.
9+
A successful timing attack may result in leaking secrets or authentication bypass.
10+
</p>
11+
</overview>
12+
13+
<recommendation>
14+
<p>
15+
Use <code>MessageDigest.isEqual()</code> method to compare results of cryptographic operations.
16+
If this method is used, then the calculation time depends only on the length of input byte arrays,
17+
and does not depend on the contents of the arrays.
18+
</p>
19+
</recommendation>
20+
21+
<example>
22+
<p>
23+
The following example uses <code>Arrays.equals()</code> method for comparing cryptographic hashes.
24+
This method implements a not-constant time algorithm:
25+
</p>
26+
<sample src="UnsafeCryptoHashComparison.java" />
27+
28+
<p>
29+
The next example example uses a safe not-constant time algorithm for comparing cryptographic hashes:
30+
</p>
31+
<sample src="SafeCryptoHashComparison.java" />
32+
33+
</example>
34+
35+
<references>
36+
<li>
37+
Wikipedia:
38+
<a href="https://en.wikipedia.org/wiki/Timing_attack">Timint attack</a>.
39+
</li>
40+
li>
41+
Common Weakness Enumeration:
42+
<a href="https://cwe.mitre.org/data/definitions/208.html">CWE-208: Observable Timing Discrepancy</a>.
43+
</li>
44+
<li>
45+
Common Weakness Enumeration:
46+
<a href="https://cwe.mitre.org/data/definitions/385.html">CWE-385: Covert Timing Channel</a>.
47+
</li>
48+
<li>
49+
Java API Specification:
50+
<a href="https://docs.oracle.com/javase/8/docs/api/java/security/MessageDigest.html#isEqual-byte:A-byte:A-">MessageDigest.isEqual() method</a>
51+
</li>
52+
</references>
53+
</qhelp>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public boolean checkHash(byte[] expectedHash, byte[] data) throws Exception {
2+
MessageDigest md = MessageDigest.getInstance("SHA-256");
3+
byte[] actualHash = md.digest(data);
4+
return MessageDigest.isEqual(expectedHash, actualHash);
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public boolean checkHash(byte[] expectedHash, byte[] data) throws Exception {
2+
MessageDigest md = MessageDigest.getInstance("SHA-256");
3+
byte[] actualHash = md.digest(data);
4+
return Arrays.equals(expectedHash, actualHash);
5+
}

0 commit comments

Comments
 (0)