You may use the UPB's OpenStack cloud to instantiate a Virtual Machine to be used for this lab! Read these instructions if you wanna know how!.
Cryptography refers to the technique of securing information and communications through use of codes, especially to prevent unauthorised access.
There are two main types:
Symmetric-key encryption is based on either stream ciphers or block ciphers.
Block ciphers have one or more block size(s) but, during transformation, the block size is always fixed. Block cipher modes operate on whole blocks and require that the last part of the data be padded to a full block if it is smaller than the current block size. There are, however, modes that do not require padding because they effectively use a block cipher as a stream cipher; such ciphers are capable of encrypting arbitrarily long sequences of bytes or bits.
Most block cipher modes require a unique binary sequence, often called an initialization vector (IV), for each encryption operation. The IV has to be non-repeating and, for some modes, random as well. The initialization vector is used to ensure distinct ciphertexts are produced even when the same plaintext is encrypted multiple times independently with the same key.
The simplest of the encryption modes is the ECB (Electronic Codebook) mode. The message is divided into blocks, and each block is encrypted separately (with the same key and no IV). The disadvantage of this method is that identical plaintext blocks are encrypted into identical ciphertext blocks, so statistical analysis can reveal the protected message:
In CBC (Cipher Block Chaining) mode, each block of plaintext is XORed with the previous ciphertext block before being encrypted. This way, each ciphertext block depends on all plaintext blocks processed up to that point. To make each message unique, a random initialization vector must be used in for first block.
There is also a CTR (Counter) mode that specifically turns the block algorithm into a stream cipher: a keystream is generated by encrypting a random IV (i.e. nonce) with the key for the first block and, for successive fragments, the IV is incremented (any deterministic function can be used) and encrypted with the same key. The plaintext is XOR-ed with the keystream (basic stream cipher operation) thus the ciphertext is obtained.
Public-key cryptography uses two separate keys, one for encryption (the public key) and one for decryption (the private key). Anyone with the public key can compute an encrypted message that only the owner of the private key can read.
RSA was the first algorithm that demonstrated this concept. Its security assumptions are based on complexity theory: computing the product of two prime numbers is easy (polynomial time), but there is no efficient algorithm for factoring them back (so far, all factorization methods are in the non-polynomial class).
The keys for the RSA algorithm are generated the following way:
The public key is made of the modulus n and the public (or encryption) exponent e.
The private key is made of the modulus n and the private (or decryption) exponent d which must be kept secret.
Encrypting a message: c = m ^ e (mod n)
Decrypting a message: m = c ^ d (mod n)
Example:
p = 29, q = 31 n = p * q = 29 * 31 = 899 phi = (p -1) * (q – 1) = (29 – 1) * (31 – 1) = 840 e = 11 d * e ≡ 1 mod phi => (d * 11) / phi will give us a remainder of one. (611 * 11) = 6721 and 6721 / 840 = 8 with remainder 1 => d = 611 C = M ^ e mod n C = 119 ^ 11 mod 899 = 595 M = C ^ d mod n M = 595 ^ 611 mod 899 = 119
It is recommended NOT to encrypt more than one block with AES in ECB mode, but in order to understand why, an image with the following header was encrypted. The encrypted photo cand be found here (.zip). Is it possible to figure out what the initial image was?
42 4D 66 CA D7 00 00 00 00 00 36 00 00 00 28 00 00 00 D0 07 00 00 35 09 00 00 01 00 18 00 00 00 00 00 30 CA D7 00 74 12 00 00 74 12 00 00 00 00 00 00 00 00 00 00
sudo apt-get install hexedit
This file (compressed as .zip) was encrypted using the following code. Can you decrypt it?
from Crypto.Cipher import AES from Crypto import Random BLOCK_SIZE = 32 PADDING = b'#' iv = b"\x00" * 16 def encrypt(key, iv, data): aes = AES.new(key, AES.MODE_CBC, iv) data = aes.encrypt(data) return data def pad(s): return s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING key = Random.new().read(BLOCK_SIZE) with open('plain.jpg', 'rb') as f: data = f.read() enc = encrypt(key, iv, pad(data)) f_out = open("secret.enc", 'wb') f_out.write(key) f_out.write(enc) f_out.close()
pycryptodome
:
pip3 install pycryptodome
In order to decrypt the ciphertext, you need to factorize n into p and q, compute phi and find d.
c = 28822365203577929536184039125870638440692316100772583657817939349051546473185 n = 70736025239265239976315088690174594021646654881626421461009089480870633400973 e = 3
sudo apt-get install python3-gmpy2 # or python-gmpy2, depending on your Python version
print(hex(message)[2:].decode("hex")) # python 2 print(bytearray.fromhex(hex(message)[2:])) # python 3
Useful gmpy2 functions:
invert(x, m)
- returns y such that x * y == 1 modulo m, or 0 if no such y exists.
Please take a minute to fill in the feedback form for this lab.