7

Of course if I apply (for example) SHA-2 to a base64 encoded string it will give me a different result versus the original data, but from a strength-perspective in terms of entropy, is there a difference?

Does having a fixed input (on a bit level, like in base64: the MSB is always 0, or byte: say, appending a bunch of 0's) to a hash reduce it's strength?

2

It does not increase the entropy.

An attacker performing a brute force attack can simply apply the same encoding you are using before hashing.

2

You're asking some good questions. The first thing you should know is that information, entropy and strings/arrays of bytes are related. The entropy of a system is the Log(Information). In this case, the Information is a String (password, base64 encoded or otherwise). However, to find the information content of a string, we don't measure a it based upon it's length and what characters are in it. Instead, we measure information based upon the Range of values it can hold.

So, a coin flip has two states: Heads or Tails. Therefore, it has one bit of information: Log2(2) = 1.

What is the entropy content of a list of 100,000 unique words? It's not every possible combination of alphabetic letters (that would be 26^6 for words of length 6 or 28 bits). It is, in fact, less than 17 bits. Why? Because we don't have more than 2^17 words in the list.

The key to understanding entropy is to understand the range of possible choices for something, then, take the Log(|RANGE|) to get the entropy.

Let's look at some examples and assume you are using SHA-512 (you didn't select a length for the SHA-2 algorithm, so I've chosen 512 bits).

This means that the max entropy for any resulting hash is capped at 512 bits. This doesn't mean the hash contains 512 bits of entropy, especially if you started with a less entropic input. Also, strictly speaking, even the SHA-512 hash doesn't quite contain 512 bits, I'm fairly certain there are some hash outputs that are not possible - it doesn't cover the entire range of possible 2^512 numbers. However, it's a reasonable upper bound.

Here are some examples. All hash outputs are 512 bits in length, however:

  1. Hash(the_result_of_a_coin_flip) = 1 bit of entropy MAX.
  2. Hash(1_rnd_byte) = 8 bits of entropy MAX.
  3. Hash(64_bytes_from_a_true_random_num_gen) = 512 MAX.
  4. Hash(64_bytes_from_a_pseudo_RNG) = 512 MAX, however it will be (much) lower if the PRNG seed is smaller.
  5. Hash(1024_bytes_from_a_true_RNG) = 512 bits MAX entropy.
  6. Hash(32_rnd_bytes_base64_encoded) = 256 bits of MAX entropy.
  7. Hash(64_rnd_bytes_base64_encoded) = 512 bits of MAX entropy.
  8. Hash('00000'+64_rnd_bytes+'00000') = 512 bits of MAX entropy.

If you look at those examples, what you'll find is that the Hash algorithm caps the entropy because you can't fit more entropy (measured in bits) into the output of the algorithm. Also, you can't create more entropy with a Hash - examples 1 & 2 show this. However, you can lose entropy to a Hash function - example 5 shows that loss (8192 bits down to 512).

Example #7 shows what you were asking, I believe. We start with 512 bits of entropy (64 bytes), base 64 encode them, then hash them. A properly built hash function should retain most of the entropy of the input up to its max output size.

Example #8 shows the answer to your second question. Prepending and/or appending a fixed set of bytes to the input doesn't change the entropy of the output. Your fixed input portion has an entropy of ZERO because there's no information in it - it's fixed (|Range| = 1) and the Log(1) = 0.

I hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.