2
$\begingroup$

Sorry about the horrible title, didn't now what to say.

I'm trying to avoid having to send an IV with every message purely to keep packet sizes down, so I thought of a method to establish a "IV Pool".

This is how I thought it should be:

Client ---- Handshake ---> Server

Server ---- Handshake ---> Client

Client and Server now have a shared 1024-bit secret

First 256-bit's of the key are used as AES Key.

Now what I thought is, could I take the next 128-bits of the secret as the IV for the first encryption, and then send a massive list of random bytes to the server to use as IV's? For example:

Client ---- Sends 1024 bytes of random ---> Server

Then the client and server both take 128-bits of the random bytes each time they send a message as the IV. That way the IV is synced across both parties and the IV does not change and is theoretically "not-predictable".

My question is, is this safe? Or does it still defeat the purpose of having an IV?

$\endgroup$
4
  • $\begingroup$ Why do you need to send an IV with every packet to begin with? If you are trying to defend against replay attacks, there are better ways to go about that. $\endgroup$
    – Thomas
    Feb 16, 2013 at 3:12
  • $\begingroup$ @Thomas - if you know of a better way - then say so. $\endgroup$
    – hunter
    Feb 16, 2013 at 5:46
  • 1
    $\begingroup$ What are you using as integrity checks? A MAC every packet or every "message" (is there a difference? I suppose you are using TCP so is a "message" defined by your application?) and are the client and server authenticated upon handshake? $\endgroup$
    – Thomas
    Feb 16, 2013 at 19:21
  • $\begingroup$ @Thomas When I say packet, I mean message. $\endgroup$ Feb 17, 2013 at 5:44

2 Answers 2

3
$\begingroup$

Sending a big block of data to be then used as initialization vectors is secure (assuming it is transferred encrypted and authenticated), but kind of defeats the purpose of "keeping the message size down".

The requirements for an initialization vector depend on the mode of operation, not on the underlying cipher (AES in your case).

For CBC mode, the initialization vector for each message should be at least not predictable by an attacker before the message is known (otherwise there are some chosen-plaintext attacks which allow decrypting your message). Old versions of SSL used the last block of the previous message, and were thus vulnerable to this attack – newer versions send an IV with each message.

One way to go here would be to use part of your 1024 bit shared secret as the seed for a CSPRNG (on both sides), and use the output of this as IVs. (Use separate generators for both directions.)

For CTR mode, the initialization vector can either be random (see above), or be simply counted up from the last counter value of the last package, and if this is decided in the protocol, you don't need to send it along with the message.

(Of course, in both cases this only holds if your messages are protected from reordering by some other mechanism – e.g. if this is done over TCP.)

Your MAC (you have a MAC, don't you?) should include the initialization vector, even if it is not sent.

There are other modes of operation, including most AEAD modes, which only require the nonce-property of the initialization vector, i.e. that it is not repeated. Then you can use a simple counter, or use an existing message number (maybe together with an identifier of the sending side).

Also note that the streams in both directions should use different keys, not the same one.

$\endgroup$
4
  • $\begingroup$ Thanks, your idea for the random number generator is a good one! I am using CBC mode so this sounds good. However I have a question, everywhere I read, it seems as if (at least to me) that the IV is not important in the decryption of the ciphertext. What I mean is, if I just use random crap for the IVs would this work or not? I've seen people using timestamps as IVs however how would you get that to the other end without sending it in the message? $\endgroup$ Feb 17, 2013 at 6:02
  • $\begingroup$ Forget that last comment. Of course the IV needs to be known, otherwise AES would be unable to "un-XOR" the message when decrypting. $\endgroup$ Feb 17, 2013 at 6:35
  • $\begingroup$ Paulo, I understand I asked this a while ago, but you mean I should use a different encryption key for each direction of packets? $\endgroup$ Apr 8, 2013 at 5:16
  • $\begingroup$ @jduncanator: Yes, this is a generally good idea. It avoids replay attacks and attacks which use a decryption oracle in one direction to decrypt messages sent in the other direction. $\endgroup$ Apr 8, 2013 at 7:48
1
$\begingroup$

I'm going a bit on a discovery path here, but I think the following protocol should hold:

  1. You generate a new key each time you use the protocol during connection establishment;
  2. You create a 128 bit counter, initially set to all zero's (or a random string, if you have left over entropy from the connection establishment);
  3. For each packet you increase the counter;
  4. Encrypt the counter (when using CBC);
  5. Use the encrypted counter as IV.

Obviously this scheme requires you to keep state between the packets, as you need to know when to update the counter.

Security warnings:

  1. Never ever make the calculated IV public;
  2. Please use authenticated mode of encryption or a MAC based on a separate key.

If you don't provide integrity/authentication of the messages then you are susceptible to an attacker changing your cipher/plain text, and you may be vulnerable to padding oracle attacks.

Basically it is impossible to use encryption correctly without having some kind of overhead. You should keep that as a general rule.

$\endgroup$
6
  • $\begingroup$ The IV becoming public wouldn't be a security flaw if it's initialized with random bits, since they are all unique and unpredictable (though there is no reason to disclose it). $\endgroup$
    – Thomas
    Feb 17, 2013 at 18:49
  • $\begingroup$ @Thomas in this specific case (CBC/zero counter/same key) it certainly is a flaw. $\endgroup$ Feb 17, 2013 at 18:58
  • $\begingroup$ I said "if it's initialized with random bits" (not known to the attacker, i.e. derived from the shared secret obtained upon connection). Of course the zero counter case is a flaw. $\endgroup$
    – Thomas
    Feb 17, 2013 at 19:04
  • 1
    $\begingroup$ @Thomas OK, fair enough. I generalized the warning because there is no need to make the IV public in this scheme, as long as key key is unique for each "session" of course. $\endgroup$ Feb 17, 2013 at 19:06
  • 1
    $\begingroup$ Point taken. Using a message counter as IV with independent session keys is probably the best solution overall. $\endgroup$
    – Thomas
    Feb 17, 2013 at 19:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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