See this answer that explains the following sequence of operations:

CipherText = IV|| AES(key1,iv,message)  
tag = hmac(key2,ciphertext)

That answer says,

You should use a different key for the HMAC. In practice tacking the sha1 sum of your encryption key is good enough.

Is it really okay to use SHA1(key1) as key2? Most advice I have says that key1 and key2 must be independent but with key2 = SHA1(key), key2 depends on key1.

Are there any theoretical or practical problems or attacks known for using key2 = SHA1(key) as the HMAC key?


We don't know. Although it seems unlikely to the extreme that there is some kind of mathematical equation that gets easier to solve when the second key relies on the first key, we probably cannot prove it. So that's it for the theoretical problems.

One practical problem is that when the key for confidentiality is obtained by the adversary (e.g. through a side channel attack) that the HMAC key is also obtained; the adversary only has to perform a SHA-1 calculation over it, after all. It depends on the use case how much of an actual problem this is - if the confidentiality is the main goal then it doesn't matter, but if the authenticity or integrity of the messages is more important then this might be a good reason to think of another scheme (or to swap the keys, and have the encryption key be dependent on the MAC key).

SHA-1 over a key can be thought of as a poor mans KBKDF (key-based key derivation function). As a KDF again we cannot prove that SHA-1 is a strong method, but as a single SHA-1 is almost identical to e.g. KDF1 or KDF2, generally we assume it is OK.

Sometimes the hash over the key is also used as a poor mans key check value (KCV). KCV's are considered public knowledge. Of course you'd be in serious problems if you'd use both the poor mans KDF and poor mans KCV over the same key in the same protocol.

As we're now getting into the realm of what constructs we generally use to achieve this goal of generating two keys out of one: usually we perform the following instead:

$$K_\textit{mac} =\operatorname{KDF}(k_\textit{master}, \texttt{"mac"})$$ $$K_\textit{enc}=\operatorname{KDF}(k_\textit{master}, \texttt{"enc"})$$

where $k_\textit{master}$ has the value of the original encryption key. $\texttt{"mac"}$ and $\texttt{"enc"}$ are labels that are part of the $\textit{info}$ string that helps to deviate the MAC and encryption keys from each other.

For instance, you could use HKDF-expand as KDF. That's a much stronger construct as HKDF uses HMAC internally. It also removes the dependency of the HMAC key on the encryption key; they now both rely solely on the original key now called the master key, which isn't used in the protocol afterwards.

As generally the KDF is only executed once per session it should not influence the performance of the protocol all that much. So usually it makes sense to play it safe rather than to use the quick and dirty method of just taking the SHA-1.

The fact that these kind of constructs are proposed together with (what I assume is CBC) encryption and HMAC makes me wary of the knowledge of the person producing the protocol. In this case the scheme was really originating from the person asking the question that you linked to.

Usually we now use an authenticated (AEAD) scheme for new protocols, and most AEAD schemes require only one key from the very start, rendering the entire discussion and additional calculations unnecessary.

| improve this answer | |
  • 3
    $\begingroup$ In case not clear: the conclusion is: yes, you can do just use SHA-1. Are there objectively better ways of achieving the same? Yes, absolutely, but they are ever so slightly less efficient. Can you avoid it altogether? Sure, use a more efficient AEAD scheme that only requires one key. $\endgroup$ – Maarten Bodewes Oct 13 '19 at 14:58

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.