Reputation: 3209
I am using Node.JS and the crypto module. I have a SHA-256 hash in hex string and would like to create a crypto.Hash instance out of it. I only found ways to hash the input string itself, but not to update or create a new hash. Am I missing something from the documentation?
I am looking for something like (for UUID though):
crypto.Hash.from("sha256", "hex", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592")
Upvotes: 0
Views: 3494
Reputation: 93968
Generally there are not many libraries that do what you ask of them. There are certainly libraries where the internal state can be retrieved and restored such as Bouncy Castle, but as yet I haven't seen it in any JavaScript library. It would be very easy to create though.
Indeed, the 256 bit (total) intermediate values after each block of 512 bits will be used as final output after the last block is hashed. So if you can "restore" those values (i.e. put them in the state) then you could continue hashing after that.
This might not be that useful though, as those values already contain the padding and message size encoded into a 64 bit representation at the end of the block. So if you continue hashing after that, that padding and length will likely be included again, but now with different values.
One trick sometimes used in smart cards is to upload the intermediate values (including number of bits hashed) before the last data to be hashed, and let the smart card perform the padding, the length encoding and the final hash block operation. This is usually performed during signature calculation over large amounts of data (because you really don't want to send a whole document to smart card).
Pretty dumb if you ask me, just directly signing using a pre-calculated hash value is the way forward. Or making sure that the large swath of data is pre-hashed, and the hash is then signed (including another pass of the hash) - that way the entire problem can be avoided without special tricks.
Upvotes: 1
Reputation: 6404
The following small example code hashes a string to a base64- and hex string encoding.
This is the output:
buf: The quick brown fox jumps over the lazy dog
sha256 (Base64): 16j7swfXgJRpypq8sAguT41WUeRtPNt2LQLQvzfJ5ZI=
sha256 (hex): d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
code:
var crypto = require('crypto');
const plaintext = 'The quick brown fox jumps over the lazy dog';
const buf = Buffer.from(plaintext, 'utf8');
console.log('buf: ' + buf);
const sha256Base64 = crypto.createHash('sha256').update(buf).digest('base64');
console.log('sha256 (Base64): ' + sha256Base64);
const sha256Hex = crypto.createHash('sha256').update(buf).digest('hex');
console.log('sha256 (hex): ' + sha256Hex);
Edit: I misunderstood the question, the task is to run several SHA-256 update calls (e.g. for different strings) and receive a (intermediate) result. Later this result should be used as "input" and the hashing should be proceeded with more update calls, finished with by "final"/"digest" to get the final sha-256 value about all parts.
Unfortunately there seems to be no way as the intermediate value is a final value and there (again) seems to be no way back because the final/digest calls make so additional computations (has to do with the underlying Merkle-Damgård constructions). The only way would be use an own written SHA-256 function and save the state of all internal registers, reset the registers when continuing and get the final value in the end.
An advice could be to grab the source code of a sha-256 implementation and save the internal states of all used variables. When proceeding you need to restore these variables and run the next update calls. I viewed some (Java) imps, and it does not look very difficult for me.
Upvotes: 0