Initialization vector -> where do I put it?

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Initialization vector -> where do I put it?

Post by Ambush Commander »

This is my first time using encryption, so I'm trying to do it right. In the examples, they strongly advise the use of initialization vectors.
In cryptography, an initialization vector (IV) is a block of bits that is combined with the first block of data in any of several modes of a block cipher. In some cryptosystems it is random and is sent with the ciphertext; in others, such as a disk encryption subsystem, it is based on some info, such as the file's inode, that does not have to be put in the ciphertext.
So, that means once I create an IV, I need to know it in order to decrypt the data fully (otherwise, the first few bits will be garbled). So where do I put the IV to retrieve it later? The Wikipedia article says that it's sent with the ciphertext, but does that mean I:

Code: Select all

$cookie = base64_encode(serialize(array($ciphertext,$iv)));
Or is there a better way? Or am I missing something here?
Last edited by Ambush Commander on Tue Jul 19, 2005 4:55 pm, edited 2 times in total.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Okay, let's see... (looks up example in a book lying around)

Code: Select all

return $iv.$crypttext;
and for the decryption,

Code: Select all

$ivsive = mcrypt_get_iv_size($td);
$iv = substr($crypttext, 0 ,$ivsize);
$crypttext = substr($crypttext, $ivsize);
Meh, so I was right. Well, not really.

EDIT - Okay, now I'm even more confused:
First, the IV should be random and variable. The whole point of it is to ensure that the same plaintext does not encrypt to the same ciphertext every time. You most certainly do lose security if the IV is constant or public.

The ciphertext should be E(IV | plaintext, key)

Second, the IV should not be part of the decryption parameters at all. You should be able to decrypt the cipher text, throw away the initial vector at the front w/o even reading it, and have your plaintext:

[IV | plaintext ] = D(ciphertext, key)

All that is public is the size of the IV.

These are well-known facts about cryptography. Check N. Kobliz's books for backup.

Unless mcrypt conforms to the above, it is very seriously flawed and should not be used.
How does one send the IV without letting it be known? Isn't the procedure described here reminiscent of salting passwords before hashing them? Now I'm just plain confused.
Post Reply