Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use MessageDigest.reset()

I've blindly followed OWASP's recommendation on hash generation in java (see here), and I'm not sure I've done it correctly. Specifically, I'm unsure about the purpose and effect of MessageDigest.reset(), and therefore when and how to use it.

  1. I'm "loading" my salt and payload by update()ing the digest several times with different values that altogether need to be signed. Should I reset() the digest beforehand? Or afterwards?
  2. Why is the digest being reset() within the loop (see the example)?

Here's my code:

MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt);
md.update(payload1);  // part 1 of payload
md.update(payload2);  // part 2 of payload
md.update(serialNumber);  // part 3 of payload
md.reset();
byte[] sig = md.digest();
for (int i=0; i<1000; i++) {
  md.reset();
  sig = md.digest(sig);
}

What I'm observing is that the signature remains the same even when serialNumber is changing. If I leave out the 'reset()' calls, the sig does change...

like image 226
Hank Avatar asked Dec 10 '12 14:12

Hank


People also ask

What is the use of MessageDigest in Java?

Message digests are secure one-way hash functions that take arbitrary-sized data and output a fixed-length hash value. A MessageDigest object starts out initialized. The data is processed through it using the update methods. At any point reset can be called to reset the digest.

Is MessageDigest thread safe?

MessageDigest is not thread safe and for the same input, it can generate different hash #816.

How do I make MessageDigest?

You can generate the message digest using the digest() method od the MessageDigest class this method computes the hash function on the current object and returns the message digest in the form of byte array. Generate the message digest using the digest method.

What is MessageDigest in Android?

Class Overview Uses a one-way hash function to turn an arbitrary number of bytes into a fixed-length byte sequence. The original arbitrary-length sequence is the message, and the fixed-length byte sequence is the digest or message digest.


2 Answers

You only need to call reset if you have already used that instance of MessageDigest. reset is being called here to clear all previous settings.

MessageDigest.getInstance is a factory method rather than a singleton so has significant overhead attached.

From MessageDigest.getInstance:

A new MessageDigest object encapsulating the MessageDigestSpi implementation from the first Provider that supports the specified algorithm is returned.

So better to re-use and avoid the overhead of calling MessageDigest.getInstance again.

like image 111
Reimeus Avatar answered Oct 17 '22 15:10

Reimeus


The code looks off to me... maybe I'm mis-reading here, but the docs say digest() implicitly resets the instance. Thus, you'd call reset() if you had 1) previously called update() and 2) needed to re-use the instance, but didn't need the results from the update() calls.

In your case, I also think you need to leave out the first call to reset(). Otherwise, you are throwing away any benefit from the salt and payloads. The call to reset() inside the loop is unnecessary, but shouldn't change the results of the calculation.

Hope that helps.

like image 22
bimsapi Avatar answered Oct 17 '22 15:10

bimsapi