Dr. Greg Bernstein
October 6th, 2021
From Wikipedia: AES
The Advanced Encryption Standard (AES), also known by its original name Rijndael, is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001.
In the United States, AES was announced by the NIST as U.S. FIPS PUB 197 (FIPS 197) on November 26, 2001. This announcement followed a five-year standardization process in which fifteen competing designs were presented and evaluated, before the Rijndael cipher was selected as the most suitable.
AES is an open standard. The details of its operation has been public for over 20 years.
" is the first (and only) publicly accessible cipher approved by the U.S. National Security Agency (NSA) for top secret information when used in an NSA approved cryptographic module."
AES is very efficient (fast, easy to implement in hardware and software)
Encryption: \(E_K(P) := E(K,P): \{0,1\}^k \times \{0,1\}^n \rightarrow \{0,1\}^n\)
Where \(K\) is the key of length \(k\) bits, \(P\) is the plaintext of length \(n\) bits
Decryption: \(E_K^{-1}(C) := D_K(C) = D(K,C): \{0,1\}^k \times \{0,1\}^n \rightarrow \{0,1\}^n\)
AES is a block cipher it works on blocks of 128 bits (16 bytes) and uses key sizes of 128 bits (16 bytes), 192 bits (24 bytes), or 256 bits (32 bytes)
From Wikipedia: AES: “AES is based on a design principle known as a substitution–permutation network, and is efficient in both software and hardware.”
From Wikipedia
Block Ciphers are used via certain block cipher modes of operation which must be carefully used to get the full protection of the algorithm.
The length of the key is vital to the security of the algorithm, you should never directly use “text” as a key to a block cipher.
From NISTIR 8319 Review of the Advanced Encryption Standard, Nicky Mouha, July 2021.
Currently, virtually all modern 64-bit processors have native instructions for AES, which includes any recent 64-bit desktop or mobile device. A study by Leech et al. estimated that the economic impact of the development of AES has totaled more than $250 billion over the past 20 years. The use of AES is ubiquitous, and the algorithm enjoys strong support in the cryptographic community.
From NISTIR 8319 Review of the Advanced Encryption Standard, Nicky Mouha, July 2021.
Examples of protocols and applications that make use of AES are Transport Layer Security (TLS), which is used by virtually all web browsers; Secure Shell (SSH); Internet Protocol Security (IPsec); Wi-Fi; the fourth-generation (4G) Long-Term Evolution (LTE); the fifth- generation New Radio (5G NR); the Zigbee and Bluetooth standards for short-range communications; chip cards (both contact and contactless), including the Europay-MasterCard- Visa (EMV) credit and debit cards; and the Personal Identity Verification (PIV) used across the US Federal Government.
AES is well known with published examples
from cryptography.hazmat.primitives.ciphers import (Cipher, algorithms, modes)
plaintext = bytes.fromhex("00112233445566778899aabbccddeeff")
key = bytes.fromhex("000102030405060708090a0b0c0d0e0f")
encryptor = Cipher(algorithms.AES(key), modes.ECB()).encryptor()
ciphertext = encryptor.update(plaintext)
print(ciphertext.hex())
# Expected output: 69c4e0d86a7b0430d8cdb78070b4c55a
decryptor = Cipher(algorithms.AES(key), modes.ECB()).decryptor()
dtext = decryptor.update(ciphertext)
print(dtext.hex())
plaintext = bytes.fromhex("00112233445566778899aabbccddeeff")
key = bytes.fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
encryptor = Cipher(algorithms.AES(key), modes.ECB()).encryptor()
ciphertext = encryptor.update(plaintext)
print(ciphertext.hex())
# Expected output: 8ea2b7ca516745bfeafc49904b496089
Will use matplotlib and numpy to get an image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
img = mpimg.imread('test.jpg')
plt.figure()
plt.imshow(img)
Screen shot of the Image tutorial page
print(f"The image size in bytes: {img.size}")
print(f"The number of dimensions in the image array: {img.ndim}")
print(f"The size of each image dimension: {img.shape}")
print(f"The type of data in the image arra: {img.dtype}")
Not to be used for security!!!
def jpgEncrypt(npimg, encrypt=True):
shape = npimg.shape
# Chop off rows and columns to be a multiple of 4
nshape = ((shape[0]//4)*4, (shape[1]//4)*4, shape[2])
cimg = np.ndarray(nshape, np.uint8)
# Encrypt by block
for i in range(0, nshape[0]//4):
for j in range(0, nshape[1]//4):
for k in range(0, 3):
mybytes = npimg[4*i:4*(i + 1), 4*j:4*(j+1), k].tobytes()
if encrypt:
cbytes = encryptor.update(mybytes)
else:
cbytes = decryptor.update(mybytes)
deserialized_bytes = np.frombuffer(cbytes, dtype=np.uint8)
cimg[4*i:4*(i + 1), 4*j:4*(j+1), k] = np.reshape(deserialized_bytes, newshape=(4, 4))
return cimg
This is suitable for “top secret” information?
The image (uncompressed) has lots of 128 bit blocks with the same information, i.e., groups of identical 4x4 pixels, the block encryption algorithm processes these into exactly the same new blocks of information!
I guess we can’t use AES?
From Block cipher mode of operation
A block cipher by itself is only suitable for the secure cryptographic transformation (encryption or decryption) of one fixed-length group of bits called a block. A mode of operation describes how to repeatedly apply a cipher’s single-block operation to securely transform amounts of data larger than a block.
Just a sample, there are more…
Mode | Encrypt Parallel | Decrypt Parallel | Random Read | Stream |
---|---|---|---|---|
ECB | Yes | Yes | Yes | No |
CBC | No | Yes | Yes | No |
CFB | No | Yes | Yes | Yes |
OFB | No | No | No | Yes |
CTR | Yes | Yes | Yes | Yes |
From Wikipedia: Block cipher mode of operation
The disadvantage of this method is a lack of diffusion. Because ECB encrypts identical plaintext blocks into identical ciphertext blocks, it does not hide data patterns well. ECB is not recommended for use in cryptographic protocols
From Wikipedia: Block cipher mode of operation
An initialization vector (IV) is a block of bits that is used by several modes to randomize the encryption and hence to produce distinct ciphertexts even if the same plaintext is encrypted multiple times.
An initialization vector has different security requirements than a key, so the IV usually does not need to be secret. For most block cipher modes it is important that an initialization vector is never reused under the same key, i.e. it must be a cryptographic nonce. Many block cipher modes have stronger requirements, such as the IV must be random or pseudorandom.
# Set up encryptor and decryptor
key = bytes.fromhex("000102030405060708090a0b0c0d0e0f")
# Need to set the initialization vetor
iv = bytes.fromhex("e0e1e2f3f4a5a6a7b8b90a0b0c0d0e0f")
encryptor = Cipher(algorithms.AES(key), modes.CBC(iv)).encryptor()
decryptor = Cipher(algorithms.AES(key), modes.CBC(iv)).decryptor()
When I use AES with CBC to encrypt my screen shot I get:
From Wikipedia: Block cipher mode of operation
The nonce is like an initialization vector
“VeraCrypt is a free open source disk encryption software for Windows, Mac OSX and Linux.”
Modes of Operation: The mode of operation used by VeraCrypt for encrypted partitions, drives, and virtual volumes is XTS.
In 2010, XTS mode was approved by NIST for protecting the confidentiality of data on storage devices. In 2007, it was also approved by the IEEE for cryptographic protection of data on block-oriented storage devices (IEEE 1619).
dm-crypt
dm-crypt is a transparent disk encryption subsystem in Linux kernel versions 2.6 and later and in DragonFly BSD. It is part of the device mapper (dm) infrastructure, and uses cryptographic routines from the kernel’s Crypto API. Unlike its predecessor cryptoloop, dm-crypt was designed to support advanced modes of operation, such as XTS, LRW and ESSIV (see disk encryption theory for further information), in order to avoid watermarking attacks.
Wikipedia: LUKS “The Linux Unified Key Setup (LUKS) is a disk encryption specification created by Clemens Fruhwirth in 2004 and was originally intended for Linux.”
LUKS is the standard for Linux hard disk encryption. By providing a standard on-disk-format, it does not only facilitate compatibility among distributions, but also provides secure management of multiple user passwords. LUKS stores all necessary setup information in the partition header, enabling to transport or migrate data seamlessly.