homework
This commit is contained in:
parent
9e3661bc44
commit
23af09eeca
@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Asymmetric Cryptography -> Key Generation: Tutorial 1
|
||||||
|
|
||||||
|
The goal of this tutorial is to learn how to generate and use asymmetric keys.
|
||||||
|
Additionally, you will learn how to encrypt and decrypt messages using generated private and public keys.
|
||||||
|
In this implementation the message is a string converted to a byte object.
|
||||||
|
Both methods encrypt and decrypt accept two args: a message and a key to perform its operation.
|
||||||
|
|
||||||
|
Your task is to:
|
||||||
|
* locate the TODOs in this file
|
||||||
|
* complete the missing part from the code
|
||||||
|
* run the test of this tutorial located in same folder.
|
||||||
|
|
||||||
|
To test run 'Asym_t.py' in your command line
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
* do not change class structure or method signature to not break unit tests
|
||||||
|
* visit this url for more information on this topic:
|
||||||
|
https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from cryptography.exceptions import *
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import padding
|
||||||
|
|
||||||
|
|
||||||
|
# TODO 1: Generate first a private key, then a public key. As a result return both values.
|
||||||
|
# Make sure you generate the keys in the correct order.
|
||||||
|
# Use recommended algorithm values where possible
|
||||||
|
# Suggested key size 2048
|
||||||
|
def generate_keys():
|
||||||
|
private = rsa.generate_private_key(
|
||||||
|
public_exponent=65537,
|
||||||
|
key_size=2048,
|
||||||
|
)
|
||||||
|
public = private.public_key()
|
||||||
|
return private, public
|
||||||
|
|
||||||
|
# TODO 2: Encrypt a passed message using the provided key
|
||||||
|
# Suggested algorithm is SHA256()
|
||||||
|
def encrypt(message, key):
|
||||||
|
try:
|
||||||
|
return key.encrypt(
|
||||||
|
message,
|
||||||
|
padding.OAEP(
|
||||||
|
mgf=padding.MGF1(algorithm=hashes.SHA256()),
|
||||||
|
algorithm=hashes.SHA256(),
|
||||||
|
label=None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except InvalidKey:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# TODO 3: Decrypt a passed message using the provided key
|
||||||
|
# Make sure using the same recommended algorithm values for encryption and decryption
|
||||||
|
# Suggested algorithm is SHA256().
|
||||||
|
def decrypt(ciphertext, key):
|
||||||
|
try:
|
||||||
|
return key.decrypt(
|
||||||
|
ciphertext,
|
||||||
|
padding.OAEP(
|
||||||
|
mgf=padding.MGF1(algorithm=hashes.SHA256()),
|
||||||
|
algorithm=hashes.SHA256(),
|
||||||
|
label=None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
This test case will verify if the provided solution by a student for Asym.py is correct.
|
||||||
|
"""
|
||||||
|
from Asym import *
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# Generate both private en public keys for each user
|
||||||
|
alex_prv, alex_pbc = generate_keys()
|
||||||
|
mike_prv, mike_pbc = generate_keys()
|
||||||
|
rose_prv, rose_pbc = generate_keys()
|
||||||
|
|
||||||
|
# Create a message
|
||||||
|
alex_message = b'This is a message for Rose: Hi Rose'
|
||||||
|
|
||||||
|
# Encrypt and decrypt a message using a user asymmetric keys
|
||||||
|
ciphertext = encrypt(alex_message, rose_pbc)
|
||||||
|
received_message = decrypt(ciphertext, rose_prv)
|
||||||
|
|
||||||
|
# Compare sent and reveived messages before encryptions and after decryption
|
||||||
|
# to check if the proccess was applied correctly
|
||||||
|
if received_message!= None and received_message == alex_message:
|
||||||
|
print("Success: The received message is properly decrypted by Rose's Private Key.")
|
||||||
|
else:
|
||||||
|
print("Fail: The received message is not properly decrypted by Rose's Private Key.")
|
||||||
|
|
||||||
|
|
||||||
|
received_message = decrypt(ciphertext, mike_prv)
|
||||||
|
if received_message== None or received_message == alex_message:
|
||||||
|
print("Fail: The received message is None or could be decrypted by Mike's Private Key!")
|
||||||
|
else:
|
||||||
|
print("Success: The received message could not be decrypted by Mike's Private Key.")
|
||||||
|
|
||||||
|
|
||||||
|
received_message = decrypt(ciphertext, alex_pbc)
|
||||||
|
if received_message== None or received_message == alex_message:
|
||||||
|
print("Fail: The received message is None or could be decrypted by Alex's Public Key!")
|
||||||
|
else:
|
||||||
|
print("Success: The received message could not be decrypted by Alex's Public Key.")
|
103
period_1/03-cryptography/302_T02_A02_ Asym_KeySaveLoad_1/Asym.py
Normal file
103
period_1/03-cryptography/302_T02_A02_ Asym_KeySaveLoad_1/Asym.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Asymmetric Cryptography -> Key Management: Tutorial 2
|
||||||
|
|
||||||
|
The goal of this tutorial is to learn how to load and store asymmetric keys on the disk.
|
||||||
|
In previous tutorial you have learned how to generate keys and use them directly to encrypt/decrypt a message,
|
||||||
|
but in many cases generated keys are stored on and loaded from a disk when they are needed for a specific application.
|
||||||
|
As a part of the loading and saving process keys are de-/serialized.
|
||||||
|
It is optionally possible to encrypted before saving using a password. In our example no passwords are needed.
|
||||||
|
Stored keys in the file system are encoded using PEM encapsulation format.
|
||||||
|
This format has BEGIN {format} and END {format} markers to separate keys.
|
||||||
|
Stored keys are located in a subdirectory called *storage*
|
||||||
|
|
||||||
|
Your task is to:
|
||||||
|
* locate the TODOs in this file
|
||||||
|
* complete the missing part from the code
|
||||||
|
* run the test of this tutorial located in same folder.
|
||||||
|
|
||||||
|
To test run 'Asym_t.py' in your command line
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
* do not change class structure or method signature to not break unit tests
|
||||||
|
* visit these urls for more information on this topic:
|
||||||
|
https://cryptography.io/en/latest/hazmat/primitives/asymmetric/serialization/
|
||||||
|
https://docs.python.org/3/library/pickle.html
|
||||||
|
"""
|
||||||
|
# from tkinter.messagebox import NO
|
||||||
|
from cryptography.exceptions import *
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import padding
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
def generate_keys():
|
||||||
|
private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048)
|
||||||
|
public_key = private_key.public_key()
|
||||||
|
return private_key, public_key
|
||||||
|
|
||||||
|
def encrypt(message, key):
|
||||||
|
try:
|
||||||
|
ciphertext = key.encrypt(message,
|
||||||
|
padding.OAEP(
|
||||||
|
mgf=padding.MGF1(algorithm=hashes.SHA256()),
|
||||||
|
algorithm=hashes.SHA256(),
|
||||||
|
label=None))
|
||||||
|
return ciphertext
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def decrypt(ciphertext, key):
|
||||||
|
try:
|
||||||
|
plaintext = key.decrypt(
|
||||||
|
ciphertext,
|
||||||
|
padding.OAEP(
|
||||||
|
mgf=padding.MGF1(algorithm=hashes.SHA256()),
|
||||||
|
algorithm=hashes.SHA256(),
|
||||||
|
label=None))
|
||||||
|
return plaintext
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# TODO 1: Store the list of keys into a given file.
|
||||||
|
# Make sure of proper PEM encoding before serialization
|
||||||
|
def save_keys(keys_file_name, keys_list):
|
||||||
|
keys_ser_list = []
|
||||||
|
for item in keys_list:
|
||||||
|
key_name, private_key, public_key = item
|
||||||
|
|
||||||
|
prv_ser = private_key.private_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||||
|
encryption_algorithm=serialization.NoEncryption()
|
||||||
|
)
|
||||||
|
pbc_ser = public_key.public_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
keys_ser_list.append((key_name, prv_ser, pbc_ser))
|
||||||
|
|
||||||
|
savefile = open(keys_file_name, "wb")
|
||||||
|
pickle.dump(keys_ser_list, savefile)
|
||||||
|
savefile.close()
|
||||||
|
|
||||||
|
# TODO2: Load all private and public keys from a given file and return those keys as a list
|
||||||
|
# Make sure of proper PEM decoding when deserializing
|
||||||
|
def load_keys(keys_file_name):
|
||||||
|
loadfile = open(keys_file_name, "rb")
|
||||||
|
keys_ser_list = pickle.load(loadfile)
|
||||||
|
loadfile.close()
|
||||||
|
|
||||||
|
keys_list = []
|
||||||
|
for item in keys_ser_list:
|
||||||
|
key_name, prv_ser, pbc_ser = item
|
||||||
|
private_key = serialization.load_pem_private_key(
|
||||||
|
prv_ser,
|
||||||
|
password=None
|
||||||
|
)
|
||||||
|
public_key = serialization.load_pem_public_key(
|
||||||
|
pbc_ser
|
||||||
|
)
|
||||||
|
keys_list.append((key_name, private_key, public_key))
|
||||||
|
return keys_list
|
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
This test case will verify if the provided solution by a student for Asym.py is correct.
|
||||||
|
"""
|
||||||
|
from Asym import *
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# Create an empty list
|
||||||
|
keys_list = []
|
||||||
|
|
||||||
|
# Generate asymmetric keys for several users
|
||||||
|
# Save all keys to the list
|
||||||
|
alex_prv, alex_pbc = generate_keys()
|
||||||
|
keys_list.append(('alex', alex_prv, alex_pbc))
|
||||||
|
|
||||||
|
mike_prv, mike_pbc = generate_keys()
|
||||||
|
keys_list.append(('mike', mike_prv, mike_pbc))
|
||||||
|
|
||||||
|
rose_prv, rose_pbc = generate_keys()
|
||||||
|
keys_list.append(('rose', rose_prv, rose_pbc))
|
||||||
|
|
||||||
|
mara_prv, mara_pbc = generate_keys()
|
||||||
|
keys_list.append(('mara', mara_prv, mara_pbc))
|
||||||
|
|
||||||
|
john_prv, john_pbc = generate_keys()
|
||||||
|
keys_list.append(('john', john_prv, john_pbc))
|
||||||
|
|
||||||
|
lily_prv, lily_pbc = generate_keys()
|
||||||
|
keys_list.append(('lily', lily_prv, lily_pbc))
|
||||||
|
|
||||||
|
# Specify the file name for key storage
|
||||||
|
keys_file_name = 'samples.keys'
|
||||||
|
# Save keys to the file
|
||||||
|
save_keys(keys_file_name, keys_list)
|
||||||
|
# Load keys
|
||||||
|
loaded_keys = load_keys(keys_file_name)
|
||||||
|
|
||||||
|
plain_message = b'This is a test message!'
|
||||||
|
|
||||||
|
# Test if a message can be encrypted/decrypted using asymmetric key combination of each user
|
||||||
|
for item in loaded_keys:
|
||||||
|
key_name, prv_key, pbc_key = item
|
||||||
|
ciphertext = encrypt(plain_message, pbc_key)
|
||||||
|
decrypted_message = decrypt(ciphertext, prv_key)
|
||||||
|
if decrypted_message == plain_message:
|
||||||
|
print(f'Success: The message is correctly encrypted and decrypted by {key_name}')
|
||||||
|
else:
|
||||||
|
print(f'Fail: The message could not be decrypted by {key_name}')
|
||||||
|
|
@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Asymmetric Cryptography -> Message Receive: Tutorial 3
|
||||||
|
|
||||||
|
The goal of this tutorial is to learn how to read a decrypted message from a file.
|
||||||
|
In previous tutorial you have learned how to store and load asymmetric keys.
|
||||||
|
When a user receives a messages it is normally encrypted.
|
||||||
|
To simplify the implementation we assume the received encrypted message is stored in
|
||||||
|
a file called *message_test.enc*. Asymmetric keys are stored in the file *samples_test.keys*.
|
||||||
|
|
||||||
|
Your task is to:
|
||||||
|
* locate the TODOs in this file
|
||||||
|
* complete the missing part from the code
|
||||||
|
* run the test of this tutorial located in same folder.
|
||||||
|
|
||||||
|
To test run 'Asym_t.py' in your command line
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
* do not change class structure or method signature to not break unit tests
|
||||||
|
* visit this url for more information on this topic:
|
||||||
|
https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/
|
||||||
|
"""
|
||||||
|
# from tkinter.messagebox import NO
|
||||||
|
from cryptography.exceptions import *
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import padding
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
def generate_keys():
|
||||||
|
private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048)
|
||||||
|
public_key = private_key.public_key()
|
||||||
|
return private_key, public_key
|
||||||
|
|
||||||
|
def encrypt(message, key):
|
||||||
|
try:
|
||||||
|
ciphertext = key.encrypt(message,
|
||||||
|
padding.OAEP(
|
||||||
|
mgf=padding.MGF1(algorithm=hashes.SHA256()),
|
||||||
|
algorithm=hashes.SHA256(),
|
||||||
|
label=None))
|
||||||
|
return ciphertext
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def decrypt(ciphertext, key):
|
||||||
|
try:
|
||||||
|
plaintext = key.decrypt(
|
||||||
|
ciphertext,
|
||||||
|
padding.OAEP(
|
||||||
|
mgf=padding.MGF1(algorithm=hashes.SHA256()),
|
||||||
|
algorithm=hashes.SHA256(),
|
||||||
|
label=None))
|
||||||
|
return plaintext
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def save_keys(keys_file_name, keys_list):
|
||||||
|
keys_ser_list = []
|
||||||
|
for item in keys_list:
|
||||||
|
key_name, private_key, public_key = item
|
||||||
|
|
||||||
|
prv_ser = private_key.private_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||||
|
encryption_algorithm=serialization.NoEncryption()
|
||||||
|
)
|
||||||
|
pbc_ser = public_key.public_bytes(
|
||||||
|
encoding=serialization.Encoding.PEM,
|
||||||
|
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
keys_ser_list.append((key_name, prv_ser, pbc_ser))
|
||||||
|
|
||||||
|
savefile = open(keys_file_name, "wb")
|
||||||
|
pickle.dump(keys_ser_list, savefile)
|
||||||
|
savefile.close()
|
||||||
|
|
||||||
|
def load_keys(keys_file_name):
|
||||||
|
loadfile = open(keys_file_name, "rb")
|
||||||
|
keys_list_ser = pickle.load(loadfile)
|
||||||
|
loadfile.close()
|
||||||
|
|
||||||
|
keys_list = []
|
||||||
|
for item in keys_list_ser:
|
||||||
|
key_name, private_key_ser, public_key_ser = item
|
||||||
|
private_key = serialization.load_pem_private_key(private_key_ser,password=None)
|
||||||
|
public_key = serialization.load_pem_public_key(public_key_ser)
|
||||||
|
|
||||||
|
keys_list.append((key_name, private_key, public_key))
|
||||||
|
return keys_list
|
||||||
|
|
||||||
|
# TODO 1: Load message from a given file and return it
|
||||||
|
# Make sure of passing proper arguments to open a file in read mode
|
||||||
|
def load_message(file_name):
|
||||||
|
load_file = open(file_name, "rb")
|
||||||
|
message_list = pickle.load(load_file)
|
||||||
|
load_file.close()
|
||||||
|
|
||||||
|
for item in message_list:
|
||||||
|
message = item
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
return None
|
@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
This test case will verify if the provided solution by a student for Asym.py is correct.
|
||||||
|
"""
|
||||||
|
from Asym import *
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# Specify file name for key storage
|
||||||
|
keys_file_name = 'samples_test.keys'
|
||||||
|
# Specify file name where the encrypted message is located
|
||||||
|
message_file_name = 'message_test.enc'
|
||||||
|
|
||||||
|
# Load encrypted message from the file
|
||||||
|
received_message = load_message(message_file_name)
|
||||||
|
|
||||||
|
# Load existing asymmetric keys
|
||||||
|
loaded_keys = load_keys(keys_file_name)
|
||||||
|
found = False
|
||||||
|
# Try to decrypt the loaded message using every existing private key
|
||||||
|
# Print the result of each decryption attempt
|
||||||
|
for item in loaded_keys:
|
||||||
|
key_name, prv_key, _ = item
|
||||||
|
decrypted_message = decrypt(received_message, prv_key)
|
||||||
|
if decrypted_message:
|
||||||
|
print(f'Sucecss: The message is decoded by {key_name}: "{str(decrypted_message,"utf-8")}"')
|
||||||
|
found = True
|
||||||
|
if not found:
|
||||||
|
print('Fail: The message could not be successfully decoded.')
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user