I have two question that I don't understand. Please help me take a look.Thanks.
What is the use of MessageDigest.isEqual function in Java?
Explain why, in some versions prior to Java SE 6 Update 17, it was vulnerable to a timing attack.
The Java MessageDigest class represents a cryptographic hash function which can calculate a message digest from binary data. When you receive some encrypted data you cannot see from the data itself whether it was modified during transportation. A message digest can help alleviate that problem.
MessageDigest is not thread safe, therefore if there are multiple requests in quick succession, different hash is returned for the same input.
Looking at a Java SE 6 Update 10 implementation, we see :
public static boolean isEqual(byte digesta[], byte digestb[]) {
if (digesta.length != digestb.length)
return false;
for (int i = 0; i < digesta.length; i++) {
if (digesta[i] != digestb[i]) {
return false;
}
}
return true;
}
While after the fix we see :
public static boolean isEqual(byte[] digesta, byte[] digestb) {
if (digesta.length != digestb.length) {
return false;
}
int result = 0;
// time-constant comparison
for (int i = 0; i < digesta.length; i++) {
result |= digesta[i] ^ digestb[i];
}
return result == 0;
}
The old implementation appears to be more efficient, since it returns false
when the first non-equal byte is found, but I'm assuming it was replaced because it might allow the caller to test how similar the two input byte arrays are to each other based on the running time of the method.
The new implementation always has the same running time (for same length arrays), since it iterates over the entire arrays (even if the arrays differ in their very first byte).
I searched where this method is called. One example is engineVerify(byte[] signature)
in com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac
class, which tests if the signature byte array passed to it is valid by comparing it to some internal byte array. Prior to the fix, by measuring the running time of that method, you could try to generate a byte array that would pass the comparison (the longer the method takes to run implies that a larger prefix of the two arrays is equal).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With