3.6 SENDING BOB A MESSAGE
EXERCISE 3.6: SENDING BOB A MESSAGE
Using either a modification of the preceding program or your AES encryptor from the beginning of the chapter, create a couple of meetup messages from Alice to Bob. Also create a few from Bob to Alice. Make sure that you can correctly encrypt and decrypt the messages.
# Suppose the following code is in a file named: ex3_6.py
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
class Padding:
@staticmethod
def pad_it_up(msg: bytes) -> bytes:
'''
This function is used to pad the message.
Technique: Determine the number of padding bytes required.
This is a number n which satisfies 1 <= n <= 16
and n + len(msg) is a multiple of 16. Pad the plaintext by appending
n bytes, each with value n. (Read more in Chapter 4 of the book
"Cryptography Engineering by Niels Ferguson, Bruce Schneier, Tadayoshi Kohno".)
'''
= 16 - len(msg) % 16
n return msg + bytes([n] * n)
@staticmethod
def unpad_it_up(msg: bytes) -> bytes:
'''this function is used to remove the pads from the message'''
= msg[-1]
n # then ignore the last n bytes
return msg[:-1*n]
# Alice and Bob's Shared Key
= bytes.fromhex('00112233445566778899AABBCCDDEEFF')
test_key
def encrypt_using_aes_ecb(plaintext: str, key: bytes) -> str:
= Padding.pad_it_up(plaintext.encode('utf-8'))
proper_plaintext = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
aesCipher = aesCipher.encryptor()
aesEncryptor = aesEncryptor.update(proper_plaintext)
ciphertext return ciphertext.hex(chr(10),-16) # this will insert '\n' between every 16-byte block.
def decrypt_using_aes_ecb(ciphertext: str, key: bytes) -> str:
= bytes.fromhex(ciphertext.replace('\n',''))
proper_ciphertext = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
aesCipher = aesCipher.decryptor()
aesDecryptor = aesDecryptor.update(proper_ciphertext)
plaintext = Padding.unpad_it_up(plaintext)
plaintext return plaintext.decode()
def EATSAform(from_codename: str, to_codename: str, date: str, location: str, time: str):
# Note that EATSA stands for East Antarctica Truth Spying Agency 😉
return f"FROM: FIELD AGENT {from_codename}\n" \
f"TO: FIELD AGENT {to_codename}\n" \
f"RE: Meeting\n" \
f"DATE: {date}\n" \
f"\nMeet me today at the {location} at {time}."
First generate the messages:
Then encrypt both of the messages:
Look at the two ciphertext outputs of these messages side-by-side.
No | Ciphertext 1 Blocks | Ciphertext 2 Blocks |
---|---|---|
1 | e5423e662cb98ca3ecf2c66b31cf1c8b | e5423e662cb98ca3ecf2c66b31cf1c8b |
2 | f7c240c61a9c1453aae2edb028fa8459 | f7c240c61a9c1453aae2edb028fa8459 |
3 | 3d6ec4443f76ebc5a8abb94879113e58 | 3d6ec4443f76ebc5a8abb94879113e58 |
4 | 88191d257c5970af6774a9f696681766 | 88191d257c5970af6774a9f696681766 |
5 | 9473f734c616d05dae998037a11f67ab | a9f7e4995ec96761b811c24953c19907 |
6 | ee0c3ea2b40c09d80e9558cacf1a60ef | f70cc1a151a388f34c59b7b83ae0fb08 |
7 | 66651c2dc32f4c25f276968d8efda22d | 4d91ea64099f6cb3dea4d1c0edcab02f |
8 | [empty] | 5a31ed03bf733b150ca46118d8fd8e95 |
Note that the first 4 ciphertext blocks are the same.
Remember that AES in its raw mode is like a code book. For every input and key, there is exactly one output, independent of any other inputs. Thus, because much of the message header is shared between messages, much of the output is also the same.
Last step, check if the ciphertexts decrypt correctly:
Or: