Python pycrypto: using AES-128 in ECB mode

In this tutorial we will check how to encrypt and decrypt data with AES-128 in ECB mode, using Python and the pycrypto library.

 

Introduction

In this tutorial we will check how to encrypt and decrypt data with AES-128 in ECB mode, using Python and the pycrypto library.

AES stands for Advanced Encryption Standard and it is a cryptographic symmetric cipher algorithm that can be used to both encrypt and decrypt information [1].

The algorithm can use keys of 128, 192 and 256 bits and operates on data blocks of 128 bits (16 bytes) [1]. We are going to use a key of 128 bits.

Since we may want to encrypt data larger than 128 bits, we need to choose a block mode. In our case, we are going to use ECB (Electronic Code Book), which uses the same unaltered key to encrypt each block of plain text [2].

In terms of security, ECB is generally a bad choice since identical plain text blocks are encrypted to identical cipher text blocks [2], which allows a possible attacker to disclose patterns in our ciphered messages. You can check here a very illustrative example of the security problems that may arise from using ECB mode.

Even for single block messages, if we repeat the same message over time, then an attacker can understand which messages are identical.

Nonetheless, ECB is very interesting for an illustrative point of view due to its simplicity, which is why we are analyzing it in this tutorial.


Installing pycrypto

As mentioned, we will use the pycrypto library to encrypt and decrypt the data with AES. The easiest way to install it is using pip, a Python package manager.

To install it via pip, simply send the following command on the command line (depending on how you have installed Python and pip, you may need to be in a specific folder such as the Scripts folder before running pip commands):

pip install pycrypto

This tutorial was tested on Python 2.7.


The code

The first thing we are going to do is importing the AES module from the pycrypto library. This module will provide the functions and classes we need to both encrypt and decrypt the data.

from Crypto.Cipher import AES

Next we need to set our secret encryption key. Since AES is a symmetric encrypton algorithm, the key is private and needs to be known only by the two communicating parties.

The length of the key needs to be 16, 24 or 32 bytes long, depending if we want to use AES-128, AES-192 or AES-256 respectively [3], as we have mentioned in the introduction.

We are going to choose an arbitrary 16 bytes key just for illustrations purposes. Note that the key chosen is not secure at all and for real scenario use cases you should use strong keys.

key = 'abcdefghijklmnop'

Next we need to call the new function of the AES module. This function  will return an object of class AESCipher [4], which provides the functions to both encrypt and decrypt the data.

This function has many optional parameters that you can check here, but we are only going to use the key and mode parameters.

The key parameter corresponds to the encryption key to be used by the algorithm and we will pass it the key we previously defined [4].

The mode parameter corresponds to the chaining mode that is used for decryption / encryption [4]. We are going to pass the value MODE_ECB, to use the electronic code book mode.

cipher = AES.new(key, AES.MODE_ECB)

Now that we have our AESCipher object, we can encrypt the data with a call to the encrypt method. As input, this method receives the plain text string and encrypts it with the provided key and configurations used in the new function call.

Remember that the length of the message to encrypt needs to be a multiple of the block size, which is 16 bytes. In this case, the plain text message I’m passing has 32 bytes and the first block is equal to the second, to later illustrate the pattern repetition on the ciphered text, from using the ECB mode.

This encrypt method call will return as output a string with the cipher text. We will also print the type of the returned value to confirm it is indeed a string.

msg =cipher.encrypt('TechTutorialsX!!TechTutorialsX!!')
print (type(msg))

To make the result more user friendly, we will convert the cipher text to its hexadecimal representation. To do it, we call the encode method on our cipher text string, passing the value “hex” as input.

print(msg.encode("hex"))

Now that we have our cipher text, we will decrypt it back to plain text. Note that since the cipher object we have created before is stateful [5], we should create a new one for decryption calling the new function again, with the same input parameters.

decipher = AES.new(key, AES.MODE_ECB)

Finally, we call the decrypt method on our new object, passing as input the ciphered text. It returns as output the original decrypted plain text, which we will print.

print(decipher.decrypt(msg))

The final source code can be seen below.

from Crypto.Cipher import AES

key = 'abcdefghijklmnop'

cipher = AES.new(key, AES.MODE_ECB)
msg =cipher.encrypt('TechTutorialsX!!TechTutorialsX!!')
print (type(msg))

print(msg.encode("hex"))

decipher = AES.new(key, AES.MODE_ECB)
print(decipher.decrypt(msg))


Testing the code

To test the code, simply run it on your Python environment of choice. I’m using IDLE, the  IDE that comes by default with the Python installation.

You should get an output similar to figure 1, which shows the results of running the program. The first thing we can see is that the output of the encrypt method is indeed a string.

Then, we can check the cipher text resulting from encrypting the input plain text. I’ve highlighted the two blocks of the cipher text and, as can be seen, they are equal because the originating blocks of plain text were also equal. This illustrates the problem of using ECB and why we should use stronger modes.

Finally, we can check the the decryption result, obtained from using the same key.

Python pycripto AES 128 ECB mode.png

Figure 1 – Output of the program.


References

[1] https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.197.pdf

[2] https://proandroiddev.com/security-best-practices-symmetric-encryption-with-aes-in-java-7616beaaade9

[3] https://www.dlitz.net/software/pycrypto/api/current/Crypto.Cipher.AES-module.html

[4] https://www.dlitz.net/software/pycrypto/api/current/Crypto.Cipher.AES-module.html#new

[5] https://www.dlitz.net/software/pycrypto/api/current/Crypto.Cipher.blockalgo.BlockAlgo-class.html#encrypt

 

Advertisements

5 Replies to “Python pycrypto: using AES-128 in ECB mode”

  1. A slight modification to that code for Python 3.7 with Pycrytodome 3.6.6 would be

    from Crypto.Cipher import AES
    key = ‘abcdefghijklmnop’
    cipher = AES.new(key.encode(“utf8”), AES.MODE_ECB)
    msg = cipher.encrypt(b’TechTutorialsX!!TechTutorialsX!!’)
    print(type(msg))
    print(msg.hex())
    decipher = AES.new(key.encode(“utf8”), AES.MODE_ECB)
    msg_dec = decipher.decrypt(msg)
    print(msg_dec)
    print(type(msg_dec))

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s