# C1. AES & PBKDF2 in Python (40 pts.)

What you need:
• Any computer with Python 2.7

## Purpose

Practice encrypting and decrypting using AES with Python. We will use only the most common form: AES-128.

# 1. "Textbook AES" -- Simplest Method

## How AES Works

As shown below, AES has uses three values:
• Plaintext -- Input in 128-bit blocks
• Key -- A fixed 128-bit value
• Ciphertext Output in 128-bit blocks

## Block Cipher Mode of Operation

First, we'll use the less secure Electronic Code Book (ECB) mode, as shown below. In this mode, each block of plaintext is processed independently.

## Example Using an Online Tool

Using a simple online tool, here's an example of AES encryption. The plaintext and key are 16 ASCII bytes, and the ciphertext is 16 bytes in hexadecimal.
 Plaintext `SECRET MESSAGE!!` Key `SECRET KEY 128 B` Ciphertext `0f 7b c9 6e 06 c0 87 3f 15 8e 08 5c e3 81 6d bb`

## Example in Python

It's very easy, because someone else has already written a handy AES library for us to use.

After importing the library, we assign values to plaintext and key and declare a new AES object. The AES object has an encrypt method that gives the same result as the online encryptor, as shown below.

```from Crypto.Cipher import AES plaintext = "SECRET MESSAGE!!" key = "SECRET KEY 128 B" cipher = AES.new(key, AES.MODE_ECB) cipher.encrypt(plaintext).encode("hex") ```

## Longer Input

Next, use the same key and mode on this plaintext:
```SECRET MESSAGE!!SECRET MESSAGE!!SECRET MESSAGE!! ```
reveals a major weakness in ECB: the output contains three repeating blocks of 128 bits.
Changing the window width makes the repetitions easier to see.

# 2. CBC Mode: Removing Patterns

## Cipher Block Chaining (CBC)

This method was invented in 1976 to remove the repeating blocks from ECB mode. Two new features are added:
• An Initialization Vector (IV) is combined with the first block before encrypting it
• The ciphertext output from each block is combined with the next block of plaintext before encrypting it

## Example Using an Online Tool

Using these values:
 Plaintext `SECRET MESSAGE!!` Key `SECRET KEY 128 B` IV `00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff`
The ciphertext begins with ae e2 4e as shown below.

## Example in Python

All we need to do is change the mode and add the iv variable.
```from Crypto.Cipher import AES plaintext = "SECRET MESSAGE!!" key = "SECRET KEY 128 B" iv = "00112233445566778899aabbccddeeff".decode("hex") cipher = AES.new(key, AES.MODE_CBC, iv) cipher.encrypt(plaintext).encode("hex") ```
The ciphertext matches the value from the online tool, as shown below.

## Longer Input

Use the same key, iv, and mode on this plaintext:
```SECRET MESSAGE!!SECRET MESSAGE!!SECRET MESSAGE!! ```
The ciphertext no longer repeats, as shown below.

# 3. Padding: Handling Arbitrary Plaintext Lengths

## PKCS7

If the plaintext in the last block of input is shorter than 16 bytes, it must be padded before it can be encrypted by AES.

One common method is PKCS7, in which the padding is always one of these 15 byte-strings, chosen to make the total length 16 bytes.

```01 02 02 03 03 03 04 04 04 04 05 05 05 05 05 06 06 06 06 06 06 07 07 07 07 07 07 07 08 08 08 08 08 08 08 08 09 09 09 09 09 09 09 09 09 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0e 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f ```

## Example

Here's HELLO encrypted with PKCS7 padding.
```from Crypto.Cipher import AES plaintext = "HELLO" + 11 * "0b".decode("hex") key = "SECRET KEY 128 B" iv = "00112233445566778899aabbccddeeff".decode("hex") cipher = AES.new(key, AES.MODE_CBC, iv) cipher.encrypt(plaintext).encode("hex") ```

# 4. Key Derivation from a Password

## PBKDF2 (Password-Based Key Derivation Function 2)

Users don't want to remember 128-bit keys and type them in. They prefer passwords. So we need a way to convert a password of any length to a key of the correct length for the encryption method.

Even if two users have the same password, they shouldn't have identical keys, so a salt value is used to make each calculation different.

The PBKDF2 algorithm uses a password, a salt, and cryptographic algorithms to create a long series of pseudorandom bytes. You can read as many bytes as you want to form a key.

This code creates a 16-byte key from a password of `Password123` and a salt of `RANDOM STUFF`

```from pbkdf2 import PBKDF2 password = "Password123" salt = "RANDOM STUFF" PBKDF2(password, salt).read(16).encode("hex") ```
This site lets you calculate simple versions of PBKDF2 online. As you can see, it has the same result for the key.
To learn a bit more about PBKDF2, execute this command at the >>> prompt:
```help(PBKDF2) ```
When we initialize an object of type PBKDF2, the __init__ function is called. I did this on a Mac; the details of the modules shown may be different on your system.
As shown above, the __init__ function requires the caller to specify the passphrase and salt parameters, and has these default values for the other parameters:
 `iterations` 1000 `digestmodule` SHA (That is, SHA-1) `macmodule` HMAC
This is the first example algorithm specified in Appendix B.1.1 of RFC 2898: PKCS #5: Password-Based Cryptography Specification Version 2.0. It's called HMAC-SHA-1.

### Challenge C1-1: Encrypt the Message (5 pts)

Encrypt this cleartext using AES-ECB:
``` SAFE AND SECURE! ```
Use the default PBKDF2 with no salt and a password of
``` 123 ```
Use the form below to get your points.
 Your Name: Ciphertext like this:      `0f7bc96e06c0873f158e085ce3816dbb`

### Challenge C1-2: Decrypt the Message (10 pts)

Decrypt this AES-ECB-encrypted ciphertext:
``` 4e45e079c9c5b019d1ee66dde12db4fd8c05933ec3d01cc9df050e3791fe9cb0 ```
The key was formed using the same one-digit PIN for both the salt and the passphrase, and default values for the other options.

Use the form below to get your points.

 Your Name: Cleartext like this:      `SAFE AND SECURE!`

### Challenge C1-3: Decrypt the Message (25 pts)

Decrypt this AES-CBC-encrypted ciphertext:
``` 4a3b101904aff330dcfdca5e7548f202f7273de7d35f7f0a51964f67d666b16167c2896095b001643cd9830a2c8e2a41 ```
The passphrase and the salt are two-digit numbers. The iv contains 128 bits, all zero.

Use the form below to get your points.

 Your Name: Cleartext like this:      `SAFE AND SECURE!`

## References

Rindjael Flash Animation (SWF File)
Block cipher mode of operation - Wikipedia