15

I'm a little bit confused how to use AES and HMAC (based on SHA-256) in a proper way when transmitting the encrypted message from server to client or vice versa

Correct me please if the following method is wrong:

  1. Take the secure key from the key file (for example we suggest to use the AES-256 and we already have a valid 256 bit length key)
  2. Generate random IV for AES-256 to be sure that the same plain text will have different encryption output.
  3. Calculate HMAC-SHA-256 using the plain text and secure key. (The first question: should I use IV for HMAC calculation? For example append to secure key?)
  4. Encrypt the plain text using AES-256.
  5. Compose message for client as following: HMAC + IV+ ENCRYPTED_MESSAGE

The biggest question is: is it possible somehow not to send IV to client but instead generate it the same way and still be crypto safe? Or is it ok to send the IV too?

I've end up with random IV generation, because it is needed that the same plain text will end up in different encryption results.

skaffman
  • 398,947
  • 96
  • 818
  • 769
Valentin
  • 860
  • 2
  • 10
  • 21

1 Answers1

15

Don't send hmac(message),aes(message). If you send the same message twice, anyone can tell. Moreover, you need to mac the cipher-text to prevent attacks such as the padding oracle attack.

IV: In general, the easy way to deal with the iv is to prepend it, since it's fixed length, to the cipher text.You can then just read off those bytes before decrypting. IV's can be public, but they must be random.

HMAC: Easiest way, if your library supports it, is to use AES in GCM mode (or, less preferably EAX). This is not actually an HMAC, but it provides authenticated encryption which is just as good.If these are not supported :

You do need to compute the hmac over both the iv and the cipher text. if || is concatenation ( which you could do with say array copy if dealing with byte arrays) then you want

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

And then send (tag,CipherText). On the other end, you run the same hmac call to regenerate the tag and the compare the received tag with the computed one. Compare the sha1 or sha256 hashes of the tags instead of directly so you don't leak where the comparison fails.

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

imichaelmiers
  • 3,449
  • 2
  • 19
  • 25
  • And what operation mode would you recommend? CBC has its overhead and we should deal with padding. I think my choice ic OFB/CFB. – Valentin Apr 30 '12 at 12:05
  • 1
    From a security point of view,they are all the same (except ECB, don't use that). Just make sure you use a fresh IV if the system takes an IV. If you want to save yourself some effort, there are authenticated modes which do not need an hmac. GCM is the best of them. What language are you using ? – imichaelmiers Apr 30 '12 at 15:20
  • I wouldn’t recommend taking the SHA1 sum of the first key as the second key. Instead you can derive two different keys with different parameters and PBKDF2 from a passphrase. The best thing is to have two independent keys and not to rely upon a (probably) weak passphrase. – Rafael Bugajewski May 17 '12 at 09:18
  • 1
    @Rafael Why would you advise against taking the SHA1 sum of the first key? I know that it would seem to have some relation there, but is there any specific reason why that's bad? Also, why do you require two separate keys, one for the AES and one for the HMAC? I can see that it might be dangerous, but any specific references on this one? – Matt Mc Jul 19 '13 at 04:51
  • Care to explain why do you need two different keys for the AES and HMAC? A brute force scenario could be against the HMAC, testing weak passwords and PBKDF2 and comparing it with the ciphertext, if they match, you found the weak password and can use it to also get back the data from the ciphertext since you know it's PBKDF2 – Cristiano Coelho May 04 '18 at 03:03