Don’t Use Low-Level Crypto Libraries

In this lesson, we'll study why you shouldn't use low-level crypto libraries.

Hopefully, we’re now in agreement that we shouldn’t roll our own crypto. It might seem that all we need to do is grab a low-level encryption library and start using it’s AES encryption and decryption functions. After all, that’s not “rolling our own crypto.”

Low-level libraries are easy to misconfigure

As we’ll see in this lesson that low-level encryption libraries present a lot of configuration choices that are easy to misuse.

For example, many low-level cryptography libraries provide support for outdated algorithms like MD5 and 3DES. And oftentimes comparisons of libraries such as Wikipedia’s show supported algorithms in a way makes it seem as though libraries with support for more algorithms are fuller featured.

Low-level libraries don’t provide guidance; instead, they force the developer to know which algorithms are safe to use. Even if the developer knows to choose a strong encryption algorithm like AES, low-level cryptography libraries still provide dangerous configuration choices. These choices include things like block mode and key size. Getting these choices wrong can result in a system that’s insecure. In contrast, a high-level encryption library is opinionated and makes these configuration choices for the developer. This makes a high-level encryption library misuse-resistant.

Let’s take a look at some of the ways it’s possible to misuse low-level encryption libraries.

AES and the ECB penguin

Have there ever been three letters that give such a feeling of safety? AES, or the Advanced Encryption Standard, has a strong pedigree. Initially called Rijndael, after its creators, Vincent Rijmen and Joan Daemen, it earned the name AES after being named the finalist in the National Institute of Standards and Technology (NIST) selection process. This selection process took several years and pitted fifteen competing algorithms against each other. During that process and after its selection, the AES algorithm has withstood tremendous scrutiny from a tremendous number of talented cryptographers.

It is the only publicly known algorithm recommended by the United States’ National Security Agency (NSA) for government secrets classified TOP SECRET. It seems no advertising copy for secure software is complete without a mention of the “bank-grade” or “military-grade” encryption it provides. And the use of AES brings a sense of relief from having satisfied those smug crypto nerds by not writing new crypto.

Pitfalls of AES

But it’s really easy to misuse.

AES is a block cipher. Probably the easiest way to misuse AES is to pick the wrong block mode.

What is a block cipher and mode?

So what’s a block mode and what’s a block cipher?

A block cipher takes two inputs—a plaintext to be encrypted and a key with which to encrypt the plaintext. It uses the key to encrypt the plaintext and produce a ciphertext. The input plaintext, the key, and the output are by definition all the same length. If you only ever had 256 bits of data to encrypt, you couldn’t ask for a better way than by using AES. As it is, however, we generally have more than 256 bits of data to encrypt.

A block mode is a set of rules that defines how to use an encryption algorithm that works on a single block in order to encrypt plaintext of arbitrary length. Choice of block mode is orthogonal to the choice of the encryption algorithm, so you can use the AES algorithm with any block mode. We’ll take a look at two block modes—electronic code book (ECB) and cipher block chaining (CBC).

ECB mode

We’ll start with ECB because it’s the simplest block mode and is the default block mode in many libraries. In ECB mode, the first block of plaintext is encrypted by itself. Then the next block of plaintext is encrypted by itself, and so on. A padding operation is used to add on data so that the final block is also a full block. The ciphertext is just the concatenation of encrypting each block of the plaintext individually. It’s the straightforward approach you’d first think of when thinking about how to apply an operation that works on a fixed-size block to plaintext of arbitrary length.

Suppose you were encrypting HTML and you had this plaintext:

<td class="foo">

which is 16 bytes, or 128 bits long. When encrypted under a 128-bit key, K, suppose this encrypts to the following in hex:

0000000 4c 69 63 65 6e 73 65 2e 74 78 74 0a 52 45 41 44

So far, so good. The only problem is that if we ever encounter plaintext block

<td class="foo">

again in this same message, that block will be encrypted into the same ciphertext that was generated last time we saw this plaintext.

0000000 4c 69 63 65 6e 73 65 2e 74 78 74 0a 52 45 41 44

This follows from encrypting each block as a completely isolated operation. Every time a given plaintext block is encrypted within a single message, it will encrypt to the same ciphertext because there are only two inputs to the encryption operation—the key and the plaintext block. Since the key is the same for the entire message, it’s clear that repeated blocks of plaintext will encrypt to the same ciphertext. This leads to repeating patterns in the ciphertext.

To see how this could create problems, consider a picture of Tux, the lovable Linux penguin, created in 1996 by Larry Ewing using the GIMP. It contains many blocks that contain just white pixels, which encrypt to one ciphertext and many blocks that contain just black pixels, which encrypt to another ciphertext.

Create a free account to view this lesson.

By signing up, you agree to Educative's Terms of Service and Privacy Policy