Assume that party 1 and party 2 each possess a key used for AES encrypting data. Assume that the key was properly randomly generated and securely passed between them.

Now I need a way for party 1 to tell party 2 which stored key to use. I was thinking of simply creating an SHA1 hash of the key and sending that with the message. My reasoning is that party 2 can easily compare that hash with the hashes of all their stored keys but there is no way for an attacked to recover the key from only it's hash.

My requirements are protection from casual snooping, not protection from people with supercomputers trying to crack this individual message. Ideally I want the only information that party 1 and party 2 share about each other is the value of the secret encryption key.

Is this plan flawed in any way, and if so is there a better way?

  • It's better style to start with a master key, and then use a KDF (e.g. HKDF) to derive multiple values from it, one for verification another the AES key, and probably a third for the MAC key. – CodesInChaos Sep 18 '13 at 10:06
  • Thanks. Although I'm more interested in the principle than in the specifics or whether SHA1 is safe for this. (FOr SHA1 in my question read "Suitable hash algorithm") – JohnB Sep 18 '13 at 10:39
  • 2
    @SajjadPourali SHA1 should still be secure for this. You need first-pre-image resistance in this context, but the attacks only find collisions. Still, I'd recommend using SHA2 instead. – CodesInChaos Sep 18 '13 at 10:57

Revealing the hash of the key may or may not be safe, depending on what you do with it. In your case, you have a key K, you show h(K) for some hash function (say SHA-1), and you also show e(K,M) for some encryption algorithm e (e.g. AES) and message M. This is safe only inasmuch as e is "different" from h, which is an ill-defined property.

For instance, imagine an encryption algorithm defined the following way: for message M and key K, hash K with SHA-1, then use the first 128 bits of the SHA-1 output with AES to process the message M. As far as encryption systems go, this one is rather good; it is as good as "raw AES" but it also accepts keys of arbitrary length. However, if you reveal SHA-1(K) then it becomes trivial to break it, even though you did not reveal K itself.

For what you want to do, you need some isolation layer between what you show for key indexation, and the encryption system. A hash function does not provide such an isolation layer "generically" between its input and its output because the output can be computed efficiently from the input (that's what the hash function is about). On the other hand, for a "good" hash function, there is no known way to compute half of the output by knowing just the other half; otherwise, fast attacks against preimage resistance would work. This yields the following scheme: from your key K, compute SHA-256(K). Split the 256-bit output into two 128-bit halves. Use the first half for indexing (you show it), and the second half for actual encryption.

  • For a somewhat realistic scheme that breaks when you reveal the hash: HMAC-SHA1 with a key longer than the block size (512 bits) breaks if you reveal the SHA1 hash of the key. – CodesInChaos Sep 18 '13 at 11:37

Why don't you affect a random key id to the keys when they are shared then identify keys based on that, putting all concerns away...

If it turns out your key generation process wasn't so random, a real concern these days with all the talk of backdoored hardware and software, your scheme would be even more easily broken. Random ids add a cheap layer of security. Unless you are ridiculously constrained on storage space, going with your scheme sounds like an unnecessary risk.

  • That could work ... – JohnB Sep 18 '13 at 13:42

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.