I know bit independence is good in SHA2 function output, but is it truly 100% secure? For example:

  • Y = SHA512(secretKeyNonce256bit)
  • A = first 32ytes / 256bits of Y, used as message encryption key
  • B = next 16bytes/128bits used as authentication HMAC key for message
  • C = next 16bytes/128bits used as access code. NON-SECRET, and known to message carrier. If user provides this code, he is given the encrypted message by the carrier.

Does having knowledge of C yield some insight into A,B? Would it be better to instead use C2=first 16 bits of SHA256(C) ?

One weakness, which extra SHA does not prevent, is if secretKey were derived from a crummy password [not the case here], C would be valuable to whoever attempted brute-like password guessing, because if a tried password produces C, it is likely that the password is correct & can produce correct A, B. Some people may mention 128bit HMAC is on a weaker side, but I think 128 / 64bit collision resistance is sufficient for my application.

  • 1
    $\begingroup$ Is there some concatenation that you're not showing, or do you really have one thing called "secretKeyNonce256bit"? $\;$ $\endgroup$
    – user991
    Jun 10 '15 at 13:01
  • $\begingroup$ Ricky: secretKeyNonce256bit = random unique "nonce" 256bit key for each message. $\endgroup$
    – Sean
    Jun 10 '15 at 15:30

There is no known exploitable relationships between the words (32/64 bit "chunks") of SHA-2 but this is always a source of cryptanalysis. There are some academic weaknesses against reduced round variants of SHA-2 but nothing against the full cipher. Still hashes are cheap so why not just use multiple hash functions?

Seed = HASH(secret)  <- This should be a KDF instead see below
A = HASH(Seed)

If you need less bits you can just chop them down (it is good enough for NIST). Here is another option.

> Seed = HASH(secret)  <- This should be a KDF instead see below 
> A = HASH(Seed XOR ConstantA)
> B = HASH(Seed XOR ConstantB)
> C = HASH(Seed XOR ConstantC)

Keep the constants the same same length as the output of HASH to avoid a biased result.

Use a KDF

I am assuming "secretKeyNonce256bit" is really a human generated password. Using a simple unsalted hash to derive a key from a low entropy secret is a bad practice. You say "not the case here" but it is unclear if you mean it is not a password or not a "weak password". If "secretKeyNonce256bit" is a 64 byte random value from a CSPRNG then ignore this but if it is the result of any human selection you really should be using a true KDF (like PBKDF2, Bcrypt or Scrypt).

  • $\begingroup$ Thanks for the answer. secretKeyNonce256bit is indeed from CSPRNG, and used only one time. I saw that MD5 output is not bit-independent, as claimed in: crypto.stackexchange.com/questions/517/… ), and got worried that some weaknesses may exist or be eventually discovered in SHA2 in this area. Interesting alternative about using "seed XOR constants". I think I will use extra hash C2=first 16 bits of SHA256(C) just to guard against any future cryptanalysis of bit-independence. $\endgroup$
    – Sean
    Jun 10 '15 at 15:44
  • $\begingroup$ Indeed; I'd recommend the seed XOR constant myself. $\endgroup$
    – Joshua
    Jul 14 '17 at 22:03

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.