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