AES in ECB mode
Tags: 100daystooffload, cryptopals, challenge, aes
Published: 2024-05-13 19:26:25

This is the seventh crypto challenge in set 1 from [cryptopals](cryptopals.com), which is the qualifying set. 

The difficulty level is relatively easy, to solve this problem I have used the programming language Go.

# Problem description

The Base64-encoded content in the file, `7.txt`, has been encrypted via AES-128 in ECB mode under the key

`YELLOW SUBMARINE`

(case-sensitive; exactly 16 characters; I like "YELLOW SUBMARINE" because it's exactly 16 bytes long, and now you do too).

Decrypt it. You know the key, after all.

Easiest way: use OpenSSL::Cipher and give it AES-128-ECB as the cipher.

Do this with code.

You can obviously decrypt this using the OpenSSL command-line tool, but we're having you get ECB working in code for a reason. You'll need it a lot later on, and not just for attacking ECB.

# Solution

Here we need to figure out how to use the crypto packages that are available in Go. The `ECB mode` is considered insecure and therefore there is no support for that mode out of the box in Go's crypto packages. However the mode is quite simple to implement anyway, and [Wikipedia](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)) give us this short explanation of the ECB mode. 

> The simplest of the encryption modes is the electronic codebook (ECB) mode. The message is divided into blocks, and each block is encrypted separately. 

The following unit test is created just to get the output for the decryption while trying out how to implement the decryption, AES with ECB mode.

```golang
func TestDecryptAESWithECBMode(t *testing.T) {
	plaintext, err := basics.DecryptAESWithECBMode("7.txt", []byte("YELLOW SUBMARINE"))
	if err != nil {
		t.Errorf("Unexpected error: %v", err)
	}

	t.Logf("Plaintext: %s", plaintext)
}
```

With that simple test we can easily see if our decryption is giving us a valid `plaintext`.

The implementation of the, `DecryptAESWithECBMode`, function looks like this.

```golang
func DecryptAESWithECBMode(filename string, key []byte) ([]byte, error) {
	ciphertext, err := decodeBase64File(filename)
	if err != nil {
		return nil, err
	}

	block, _ := aes.NewCipher(key)
	plaintext := make([]byte, len(ciphertext))
	blockSize := len(key)

	for start, end := 0, blockSize; start < len(ciphertext); start, end = start+blockSize, end+blockSize {
		block.Decrypt(plaintext[start:end], ciphertext[start:end])
	}

	return plaintext, nil
}
```

Here we are reusing the, `decodeBase64File`, function from the previous challenge to read the base64 encoded content from the file.

Then we create a new AES cipher block (`aes.NewCipher(key)`) based on the given key. The for loop is doing the `ECB mode` by decrypting each block in the ciphertext and adds it to the plaintext variable.

The complete solution can be found on [GitHub](https://github.com/stefanalfbo/cryptopals). 

# Conclusion

This challenge is all about to learn to know your cryptographic libraries in the programming language you are using.

There is also a lot of parallels that can be drawn by comparing the ECB mode with the XOR implementations done in previous challenges.
 
# References

* [Set 1 - Challenge 7](https://cryptopals.com/sets/1/challenges/7)
* [crypto/aes](https://pkg.go.dev/crypto/aes)