Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MessageDigest.update() before digest()?

Tags:

java

hash

I have found the following example code (somewhere on the web, can't remember where):

public static byte[] produce(final byte[] data)
        throws NoSuchAlgorithmException{
    MessageDigest digest = MessageDigest.getInstance(ALGORITHM);
    digest.reset();
    digest.update(data);
    byte[] ret = digest.digest(data);
    for (int i = 0; i < HASH_ITERATIONS; i++) {
        digest.reset();
        ret = digest.digest(ret);
    }
    return ret;
}

What bothers me is that the docs says that digest() already calls update() on its own with the passed input:

Performs a final update on the digest using the specified array of bytes, then completes the digest computation. That is, this method first calls update(input), passing the input array to the update method, then calls digest().

Additionally, after the call to update(), the MessageDigest object's state becomes 1.
After a call to digest() (next in the code) it returns to be simply 0.
Finally, when stepping through while debugging, I can clearly see that the data is being manipulated.

So, is it safe to remove the call to update()?

Note that I wouldn't bother anyone with that question if it weren't a big security issue.

like image 516
Poni Avatar asked Mar 03 '12 23:03

Poni


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

You are right, it is safe to remove update in your code. And more, by calling update(data) and then calling digest(data) you actually calculating digest of different message that contains data twice. I think is not what you need.

The common use case of digest(byte[]) is calculation of digest of complete data block (i.e. password). The update(byte[]) in pair with digest() used when you need to calculate digest of data coming by parts:

int read = 0; 
while ((read = fis.read(buffer)) != -1) {
    md.update(buffer, 0, read);
};
byte[] digest  = md.digest();
like image 104
Mersenne Avatar answered Oct 11 '22 10:10

Mersenne