Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MessageDigest.isEqual function use in Java

I have two question that I don't understand. Please help me take a look.Thanks.

  1. What is the use of MessageDigest.isEqual function in Java?

  2. Explain why, in some versions prior to Java SE 6 Update 17, it was vulnerable to a timing attack.

like image 588
user5545809 Avatar asked Nov 10 '15 09:11

user5545809


People also ask

What does MessageDigest do in java?

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.

Is MessageDigest thread safe?

MessageDigest is not thread safe, therefore if there are multiple requests in quick succession, different hash is returned for the same input.


1 Answers

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).

like image 139
Eran Avatar answered Oct 13 '22 12:10

Eran