Take the 2-minute tour ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

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?

share|improve this question
    
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. –  Thomas Feb 16 '13 at 3:12
    
@Thomas - if you know of a better way - then say so. –  hunter Feb 16 '13 at 5:46
1  
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? –  Thomas Feb 16 '13 at 19:21
    
@Thomas When I say packet, I mean message. –  jduncanator Feb 17 '13 at 5:44

2 Answers 2

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.

share|improve this answer
    
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). –  Thomas Feb 17 '13 at 18:49
    
@Thomas in this specific case (CBC/zero counter/same key) it certainly is a flaw. –  owlstead Feb 17 '13 at 18:58
    
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. –  Thomas Feb 17 '13 at 19:04
1  
@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. –  owlstead Feb 17 '13 at 19:06
1  
Point taken. Using a message counter as IV with independent session keys is probably the best solution overall. –  Thomas Feb 17 '13 at 19:09

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.

share|improve this answer
    
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? –  jduncanator Feb 17 '13 at 6:02
    
Forget that last comment. Of course the IV needs to be known, otherwise AES would be unable to "un-XOR" the message when decrypting. –  jduncanator Feb 17 '13 at 6:35
    
Paulo, I understand I asked this a while ago, but you mean I should use a different encryption key for each direction of packets? –  jduncanator Apr 8 '13 at 5:16
    
@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. –  Paŭlo Ebermann Apr 8 '13 at 7:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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