When to use MessageDigest.reset()
Asked Answered
M

2

5

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

Masao answered 10/12, 2012 at 14:12 Comment(1)
possible duplicate of Do I need to call MessageDigest.reset() before using it?Abysm
R
10

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.

Robotize answered 10/12, 2012 at 14:18 Comment(4)
So the OWASP example and my code are wrong, yes? If I always get a new instance, I don't need reset at all?Masao
I would go with reset & re-use :)Robotize
@Masao - You aren't always getting a new instance as .getInstance is outside of the loop. Using .reset is fine here.Stretto
Thanks, your responses and a dose of thinking-about-them(tm) has completely answered my question!Masao
D
7

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.

Drivein answered 10/12, 2012 at 15:22 Comment(1)
Totally agree, the original code was off wrt first reset() call. Thanks for the pointer regarding implicit reset!Masao

© 2022 - 2024 — McMap. All rights reserved.