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.
update()
ing the digest several times with different values that altogether need to be signed. Should I reset()
the digest beforehand? Or afterwards?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...
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.
MessageDigest is not thread safe and for the same input, it can generate different hash #816.
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.
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.
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.
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.
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