Here’s a clever comment from Rex Mundi on the story of a newspaper deliveryman being viciously attacked by a number of drunk policemen. The policemen were charged, and one of them “has been given a conditional sentence without jail time after pleading guilty” today. (The others’ trials are not complete yet)

His comment is:

So does this mean that off-duty newspaper deliverymen may anticipate no jail time if they get drunk and assault an off-duty police officer?

I’ve been looking into encryption methods recently, and came across this little surprise about cipher block chaining, or CBC, as it is used for block ciphers.

Block ciphers only encrypt messages of a fixed length, which depends on the cipher. To encrypt longer messages one breaks them up into blocks with the block cipher’s length and then individually encrypts these blocks. The receiver decrypts all the encrypted blocks and pastes the original message together. So for example, if your message is 2 kilobytes long (one ordinary page of writing), and the block cipher length is 32 bytes, then 2 kilobytes / 32 bytes = 2 * 1024 / 32 = 64 blocks of 32 bytes each will be encrypted. (Padding may or may not be necessary)

The idea of cipher block chaining is that if such a long message contains identical blocks, or two messages contain identical blocks, then you can tell that from the encrypted parts: they will be the same. Whoever has access to the encrypted message, and if they know the block cipher employed, then they can extract these blocks. While they cannot decrypt the individual blocks, they can compare them. Such is the world of cryptography that there are cases where it should be made difficult to tell that one message contains parts of a different message, or repeats itself.

Cypher Block Chaining

One solution, and the most commonly used “mode of operation” for a block cipher (see 1 , 2 , 3 ) is called Cipher Block Chaining. The idea is to introduce an additional block, called “initial vector”. This block is XOR-ed with the first block to be encrypted. The result is encrypted, and yields the first encrypted block to be sent. This block is however also XOR-ed with the next block to be encrypted. The result is encrypted, and yields the second encrypted block to be sent, and so on. Let’s generalize, and describe more accurately:

Suppose our numbering is such that the first block has number 1 (not 0 as is common).

Let P(i) be the i-th block of the plain text message.

Let E(X) be the result of encrypting the (plain text) block X.

Let D(Y) be the result of decrypting the (encrypted) block Y.

Let C(i) be the i-th encrypted (cipher) block.

Then encryption with Cipher Block Chaining can be formalized as:

C(0) := IV, the initial vector
C(i) := E( P(i) XOR C(i-1))

If the receiver knows the initial vector as well as the block cipher’s encryption key they can completely decrypt the message. Decryption is formalized like this:

C(0) := IV, the initial vector
P(i) := D( C(i) ) XOR C(i-1)

Decrypting with a Different Initial Vector

Finally I can point out what surprised me: it is that when decrypting, the blocks P(2), P(3), P(4), and so on do not depend on the initial vector IV that was used for encryption! Only P(1), the first decrypted block, depends on IV, while the other parts of the decrypted message will be the same regardless of IV.

In this way, the contribution of the initial vector is very different from the encryption key! And it is rather nice to see that it need not be any stronger, since it provides the function it is designed for: to hide the information about identical blocks.

And so, if the message is prepended by the the encrypter with some arbitrary initial block, the receiver does not need to know the initial vector used for encryption. After decrypting with some arbitrarily chosen initial vector (all 0′s, for example) they can just throw away the first block; the remaining blocks will represent the encrypted message.

Sample Code with AES and openssl

Here is some rather simple code to illustrate the effect. It is based on one of the Rijndael block ciphers, AES-256 (see Advanced Encryption Standard), and the openssl libary. The openssl options forÂ enc, “symmetric cipher routines”,are available through man enc

echo "The symmetric cipher commands allow data to be encrypted or decrypted using various block and stream ciphers" > msg.in
# Encrypt msg.in with some key and an initial vector
openssl enc -aes-256-cbc -K 1234567890123456 -iv 1234567890123456 -in msg.in -out msg.crypt
echo Decrypt with both the right key and the right iv
openssl enc -d -aes-256-cbc -K 1234567890123456 -iv 1234567890123456 -in msg.crypt
echo Decrypt with the right key but a different iv
# Pipe into 'od -cx' because there will likely be non-displayable characters. msg.crypt is a properly binary file
openssl enc -d -aes-256-cbc -K 1234567890123456 -iv ABCDEF1234560FED -in msg.crypt | od -cx
echo Compare with the output with the right key and the right iv
openssl enc -d -aes-256-cbc -K 1234567890123456 -iv 1234567890123456 -in msg.crypt | od -cx

When executed in a UNIX shell, and all the required programs are available, the output is: