diff --git a/.gitignore b/.gitignore index 2d8364d..9deb4b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ ctext -key \ No newline at end of file +key + +*.pem diff --git a/alice.py b/part1/alice.py similarity index 80% rename from alice.py rename to part1/alice.py index ebdc80f..13c4c5c 100644 --- a/alice.py +++ b/part1/alice.py @@ -5,7 +5,8 @@ from Crypto.Random import get_random_bytes # Generate new secret key with open('key', 'wb') as f: - f.write(get_random_bytes(16)) + k1 = get_random_bytes(16) + f.write(k1) plaintext = input("Please input the message: ") @@ -18,8 +19,10 @@ plaintext = pad(plaintext, 16) with open('key', 'rb') as f: aes_key = f.read() +assert k1 == aes_key + # Encrypt and send (write) message -cipher = AES.new(aes_key, AES.MODE_CBC) +cipher = AES.new(aes_key, AES.MODE_CBC, iv=b'0'*16) ciphertext = cipher.encrypt(plaintext) diff --git a/bob.py b/part1/bob.py similarity index 69% rename from bob.py rename to part1/bob.py index 78ef585..5a56db1 100644 --- a/bob.py +++ b/part1/bob.py @@ -5,14 +5,14 @@ from Crypto.Util.Padding import unpad with open('key', 'rb') as f: aes_key = f.read() -cipher = AES.new(aes_key, AES.MODE_CBC) +cipher = AES.new(aes_key, AES.MODE_CBC, iv=b'0'*16) # Read message and decrypt with open('ctext', 'rb') as f: ciphertext = f.read() -plaintext = unpad(cipher.decrypt(ciphertext), 16) +plaintext = unpad(cipher.decrypt(ciphertext), 16).decode() print(f'Plaintext: {plaintext}') diff --git a/part2/alice.py b/part2/alice.py new file mode 100644 index 0000000..63e6329 --- /dev/null +++ b/part2/alice.py @@ -0,0 +1,20 @@ +from Crypto.PublicKey import RSA +from Crypto.Cipher import PKCS1_OAEP + +# Read Bob's public key +with open("bob_public.pem", "rb") as f: + public_key = RSA.import_key(f.read()) + +# Get the message from the command line +message = input("Enter a message: ").encode() + +# Create a cipher object using Bob's public key +cipher = PKCS1_OAEP.new(public_key) + +# Encrypt the message +ciphertext = cipher.encrypt(message) + +# Write the ciphertext +with open("ctext", "wb") as f: + f.write(ciphertext) + diff --git a/part2/bob.py b/part2/bob.py new file mode 100644 index 0000000..52cd9ff --- /dev/null +++ b/part2/bob.py @@ -0,0 +1,38 @@ +from Crypto.PublicKey import RSA +from Crypto.Cipher import PKCS1_OAEP +import os + +# Check if keys already exist +if not os.path.exists("bob_private.pem"): + key = RSA.generate(2048) + + private_key = key.export_key() + public_key = key.publickey().export_key() + + # Save the private key + with open("bob_private.pem", "wb") as f: + f.write(private_key) + + # Save the public key + with open("bob_public.pem", "wb") as f: + f.write(public_key) + + print("Generated and saved Bob's public and private keys.") + +if not os.path.exists('ctext'): + print('No ctext found. Run alice.py') + exit(0) + +# Read the private key +with open("bob_private.pem", "rb") as f: + private_key = RSA.import_key(f.read()) + +# Read the ciphertext +with open("ctext", "rb") as f: + ciphertext = f.read() + +cipher = PKCS1_OAEP.new(private_key) + +# Decrypt +message = cipher.decrypt(ciphertext) +print("Decrypted message:", message.decode()) diff --git a/part3/speed-test.py b/part3/speed-test.py new file mode 100644 index 0000000..81b1f17 --- /dev/null +++ b/part3/speed-test.py @@ -0,0 +1,99 @@ +from Crypto.PublicKey import RSA +from Crypto.Cipher import PKCS1_OAEP, AES +from Crypto.Util.Padding import pad, unpad +from Crypto.Random import get_random_bytes + +import time + +plaintext = input("Please input the test message: ").encode() +IV = b'0' * 16 + +def encrypt_aes(key: bytes, plaintext: bytes) -> bytes: + plaintext = pad(plaintext, 16) + + cipher = AES.new(key, AES.MODE_CBC, iv=IV) + + return cipher.encrypt(plaintext) + +def decrypt_aes(key: bytes, ciphertext: bytes) -> bytes: + + cipher = AES.new(key, AES.MODE_CBC, iv=IV) + + return unpad(cipher.decrypt(ciphertext), 16) + + + +for size in (128, 192, 256): + + e_times = [] + d_times = [] + + for n in range(100): + aes_key = get_random_bytes(size // 8) + + start = time.time() + ciphertext = encrypt_aes(aes_key, plaintext) + end = time.time() + + e_times.append(end - start) + + start = time.time() + decrypt_aes(aes_key, ciphertext) + end = time.time() + + d_times.append(end - start) + + e_avg = sum(e_times) / len(e_times) + d_avg = sum(d_times) / len(d_times) + + print(f'AES {size} key encrpytion average: {e_avg * 1000} ms') + print(f'AES {size} key decryption average: {d_avg * 1000} ms\n') + +def encrypt_rsa(public_key: bytes, plaintext: bytes) -> bytes: + cipher = PKCS1_OAEP.new(public_key) + return cipher.encrypt(plaintext) + +def decrypt_rsa(private_key: bytes, ciphertext: bytes) -> bytes: + cipher = PKCS1_OAEP.new(private_key) + return cipher.decrypt(ciphertext) + +for size in (1024, 2048, 4096): + + e_times = [] + d_times = [] + + for n in range(100): + key = RSA.generate(size) + + private_key = key + public_key = key.publickey() + + start = time.time() + ciphertext = encrypt_rsa(public_key, plaintext) + end = time.time() + e_times.append(end - start) + + start = time.time() + decrypt_rsa(private_key, ciphertext) + end = time.time() + d_times.append(end - start) + + e_avg = sum(e_times) / len(e_times) + d_avg = sum(d_times) / len(d_times) + + print(f'RSA {size} key encrpytion average: {e_avg * 1000} ms') + print(f'RSA {size} key decryption average: {d_avg * 1000} ms\n') + + + + + + + + + + + + + +