Heads up: This post is over two years old. Things move fast — the code, tools, or opinions here may be outdated.

Encryption operating modes: ECB vs CBC

← PreviousSed: simple pattern address usage
Next →Sed & awk examples

Today I overheard two colleagues discussing one of my favorite subjects: encryption. The discussion was about that encrypting data (with a normal block cipher) was working perfectly in ECB mode, but not in CBC mode. So, this all leads up to the question: what is ECB and CBC? And when should you use them? Although this post has some PHP code in it, it is applicable for every other language.

The basics

Lets start off with the basics of a block cipher encryption. In order to encrypt data, we need to have 2 pieces of information we need to feed into the encryption-function: the message and the key. The message in this case could be anything: a string, binary data, numbers, a file. It doesn’t matter. The key is the secret that makes it (almost) impossible to decrypt the encrypted data if you don’t have it. But with it, decrypting is easy (just like the correct key makes it a lot easier to open a lock).

The actual encryption method we will use is not really that important, as long as it is a block cipher. Now, block ciphers are algorithms that use 1 single key for both encryption and decryption (also known as a symmetrical cipher). Another property is that they act on a block of data, instead of just a single bit or byte at the time (which is what stream ciphers would do).

If you have a large message (a 1MB image for instance), it has to be split up into smaller blocks of exactly the length of your key. If you use a 64bit key, you have blocks of 64 bits (or 8 bytes) each will be encrypted or decrypted. A 256 bit key gives you blocks of 32 bytes etc.

It is always possible that your message will not be exactly a multiple of your key length but it still should be possible to encrypt a 9 byte message with a 64bit key. In order to make this work, we can apply a padding-scheme to fill up the last block. However, depending on the operation mode, padding might not be needed.

+--------+--------+
| BLOCK1 | BLOCK2 |
+--------+--------+
|12345678|9PPPPPPP|
+--------+--------+

As you can see, the last block (block2) has some extra padding (P) which has to be stripped of by the decryption methods. Normally, this is all already taken care of by the encryption/decryption routines you use.

Operation modes

We only discuss 2 operation modes but there are more. A good explanation about these modes can be found [here][1] at wikipedia. The operation mode specifies how blocks “interconnect” with each other and every mode has some advantages and disadvantages. We will talk only about ECB and CBC, since these are the most common used. Other modes, like CFB or OFB are block ciphers that act like stream ciphers, but we don’t discus them here.

ECB

ECB stands for Electronic CodeBook and is the easiest mode. Every block will be concatenated to the next block so it couldn’t be simpler. However, this results in some issues:

First of all, every block of data is encrypted with only the message and key as input. Suppose you encrypt the text “HELLOYOU” with a 64-bit block size algorithm (like blowfish). This would fit perfectly inside one block since it’s 8 bytes (or 64 bits) long. Now this text is repeated 10 times, this means that your encrypted code will consists of 10 time the same encrypted output. Let’s see an example in PHP:

{% highlight php startinline=True %}{% raw %}

][2] Let's take a look at an example: {% highlight php startinline=True %}{% raw %} mcrypt_enc_get_iv_size() function to determine the size of the IV. * The $iv should be randomized for each encryption. It should not be a constant. This would mean that the encryption would become deterministic again. ## Conclusion Playing around with the various operating modes shows that there are many things you need to consider. Don't expect that everything is safe just because you encrypt your data. Without proper knowledge, this means absolutely nothing. Having said this, using a rule of thumb: don't use ECB, but always CBC with random IV's seem to work for most people. And of course, always use the best cipher algorithm that is available. [1]: http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation [2]: /images/uploads/2010/12/Cbc_encryption.png
← PreviousSed: simple pattern address usage
Next →Sed & awk examples