before and after using a cryptographic hash function
arrays, checksum, cryptographic-hash-function, hex, java
Solution
There are two parts to this:
- Why do we convert a String to a byte array before digesting?
- Why do we convert the digest to hexadecimal?
The first answer is that digests only work on byte arrays. They have no knowledge of Strings, numbers or any other data type. Just bytes. So, we take a `String` object and convert it into a byte array using some form of text encoding such as UTF-8.
Note that the encoding is important: I can encode the string "hello world" in UTF-8, or UTF-16, or US-ASCII, or any number of other encodings. If I choose UTF-8 it will generate 11 bytes of output (since "hello world" is 11 characters long), but UTF-16 will generate 22 bytes of output. These two encodings will produce different digests, so knowing the encoding is vitally important.
The second answer is that digests are often used in string-based protocols such as HTTP cookies, for storing password hashes in text columns in databases, for adding PGP signatures to email messages and so on.
Since the digest produces a raw byte array it needs to be re-encoded into something text-friendly. This is why hexadecimal (or, more likely, base-64) is used.
For example, sticking with the "hello world" example, let's say the UTF-8-encoded digest turns into a byte array with the following values: `4 27 125 8 0 22 90 7` (for my mythical 8-byte digest function). If I tried to interpreted that as a UTF-8 string then I'd get a lot of garbage: 0 is not a printable character. Encoding it in hex means I can print it out in a meaningful way, or add it to my PGP email, or whatever.
Does that make sense?
Problem
After reviewing multiple online references for generating Java MD5 and SHA* hashes, i have noticed that the plain-text (String of File) undergoes certain prep before & after it is fed to the Digest object for generating hashes. Specifically, data is first converted to byte-array, then fed to the digest, then the output hash is converted to hexadecimal stream. Why all these byte and hexadecimal conversions ? PS: I guess the answer is tied to the how Java and the Digest object do their business, and my motive/s in asking this question is to understand this behavior, and possibly obtain references to some documentation/literature that explains this in-depth. Danke!