TP04 finished and testes

This commit is contained in:
Tiago Sousa 2024-03-16 17:11:11 +00:00
parent a6c894ed56
commit b726a165a4
Signed by: tiago
SSH key fingerprint: SHA256:odOD9vln9U7qNe1R8o3UCbE3jkQCkr5/q5mgd5hwua0
2 changed files with 77 additions and 47 deletions

View file

@ -1,11 +1,11 @@
import argparse import argparse
import os import os
import cryptography.hazmat.primitives.serialization as serialization
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dh from cryptography.hazmat.primitives.asymmetric import dh
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from cryptography.hazmat.primitives.kdf.hkdf import HKDF from cryptography.hazmat.primitives.kdf.hkdf import HKDF
import cryptography.hazmat.primitives.serialization as serialization
from cryptography.hazmat.primitives.serialization import ( from cryptography.hazmat.primitives.serialization import (
Encoding, Encoding,
NoEncryption, NoEncryption,
@ -13,106 +13,125 @@ from cryptography.hazmat.primitives.serialization import (
PublicFormat, PublicFormat,
) )
p = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF
g = 2
params = dh.DHParameterNumbers(p, g).parameters()
def setup(user): def setup(user):
parameters = dh.generate_parameters(generator=2, key_size=512) private_key = params.generate_private_key()
private_key = parameters.generate_private_key()
public_key = private_key.public_key() public_key = private_key.public_key()
skey = open(f"{user}.sk", 'wb') skey = open(f"{user}.sk", "wb")
pkey = open(f"{user}.pk", 'wb') pkey = open(f"{user}.pk", "wb")
skey.write(private_key.private_bytes(encoding=Encoding.PEM, format=PrivateFormat.PKCS8, encryption_algorithm=NoEncryption())) skey.write(
pkey.write(public_key.public_bytes(encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo)) private_key.private_bytes(
encoding=Encoding.PEM,
format=PrivateFormat.PKCS8,
encryption_algorithm=NoEncryption(),
)
)
pkey.write(
public_key.public_bytes(
encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo
)
)
skey.close() skey.close()
pkey.close() pkey.close()
def encrypt(user,filename): def encrypt(user, filename):
peer_pkey_file = open(f"{user}.pk", 'rb') peer_pkey_file = open(f"{user}.pk", "rb")
if peer_pkey_file is None: if peer_pkey_file is None:
print(f"No public key found for {user}") print(f"No public key found for {user}")
return return
file_r = open(filename, 'rb') file_r = open(filename, "rb")
if file_r is None: if file_r is None:
print(f"File {filename} not found") print(f"File {filename} not found")
return return
# FIX: Add try
parameters = dh.generate_parameters(generator=2, key_size=512) skey = params.generate_private_key()
skey = parameters.generate_private_key() peer_pkey = serialization.load_pem_public_key(peer_pkey_file.read())
peer_pkey= serialization.load_pem_public_key(peer_pkey_file.read()) if not isinstance(peer_pkey, dh.DHPublicKey):
derived_key = None
if isinstance(peer_pkey, dh.DHPublicKey):
shared_key = skey.exchange(peer_pkey)
derived_key = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data').derive(shared_key)
else:
print("Error: Invalid key type") print("Error: Invalid key type")
return return
shared_key = skey.exchange(peer_pkey)
derived_key = HKDF(
algorithm=hashes.SHA256(), length=32, salt=None, info=None
).derive(shared_key)
message = file_r.read() message = file_r.read()
chacha = ChaCha20Poly1305(derived_key) chacha = ChaCha20Poly1305(derived_key)
nonce = os.urandom(12) nonce = os.urandom(12)
ciphertext = chacha.encrypt(nonce, message, None) ciphertext = chacha.encrypt(nonce, message, None)
file_w = open(f"{filename}.enc", 'wb') file_w = open(f"{filename}.enc", "wb")
nonce_ciphertext = mkpair(nonce, ciphertext) nonce_ciphertext = nonce + ciphertext
to_send = mkpair(peer_pkey.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo), nonce_ciphertext) pkey_bytes = skey.public_key().public_bytes(
Encoding.DER, PublicFormat.SubjectPublicKeyInfo
)
to_send = mkpair(pkey_bytes, nonce_ciphertext)
file_w.write(to_send) file_w.write(to_send)
file_r.close() file_r.close()
file_w.close() file_w.close()
skey_file.close()
peer_pkey_file.close() peer_pkey_file.close()
def decrypt(user,filename): def decrypt(user, filename):
skey_file = open(f"{user}.sk", 'rb') skey_file = open(f"{user}.sk", "rb")
if skey_file is None: if skey_file is None:
print(f"No private key found for {user}") print(f"No private key found for {user}")
return return
file_r = open(filename, 'rb') file_r = open(filename, "rb")
if file_r is None: if file_r is None:
print(f"File {filename} not found") print(f"File {filename} not found")
return return
message_bytes = file_r.read() message_bytes = file_r.read()
peer_pkey_bytes, ciphertext = unpair(message_bytes) peer_pkey_bytes, ciphertext = unpair(message_bytes)
# FIX: Add try
skey = serialization.load_pem_private_key(skey_file.read(), None) skey = serialization.load_pem_private_key(skey_file.read(), None)
peer_pkey = serialization.load_pem_public_key(peer_pkey_bytes) peer_pkey = serialization.load_der_public_key(peer_pkey_bytes)
derived_key = None if not isinstance(skey, dh.DHPrivateKey) or not isinstance(
if isinstance(skey, dh.DHPrivateKey) and isinstance(peer_pkey, dh.DHPublicKey): peer_pkey, dh.DHPublicKey
shared_key = skey.exchange(peer_pkey) ):
derived_key = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=b'handshake data').derive(shared_key)
else:
print("Error: Invalid key type") print("Error: Invalid key type")
return return
nonce, encrypted_message = unpair(ciphertext) shared_key = skey.exchange(peer_pkey)
derived_key = HKDF(
algorithm=hashes.SHA256(), length=32, salt=None, info=None
).derive(shared_key)
nonce = ciphertext[:12]
encrypted_message = ciphertext[12:]
chacha = ChaCha20Poly1305(derived_key) chacha = ChaCha20Poly1305(derived_key)
message = chacha.decrypt(nonce, encrypted_message, None) message = chacha.decrypt(nonce, encrypted_message, None)
file_w = open(f"{filename}.decrypt", 'wb') file_w = open(f"{filename}.dec", "wb")
file_w.write(message) file_w.write(message)
file_r.close() file_r.close()
file_w.close() file_w.close()
skey_file.close() skey_file.close()
def mkpair(x, y): def mkpair(x, y):
""" produz uma byte-string contendo o tuplo '(x,y)' ('x' e 'y' são byte-strings) """ """produz uma byte-string contendo o tuplo '(x,y)' ('x' e 'y' são byte-strings)"""
len_x = len(x) len_x = len(x)
len_x_bytes = len_x.to_bytes(2, 'little') len_x_bytes = len_x.to_bytes(2, "little")
return len_x_bytes + x + y return len_x_bytes + x + y
def unpair(xy): def unpair(xy):
""" extrai componentes de um par codificado com 'mkpair' """ """extrai componentes de um par codificado com 'mkpair'"""
len_x = int.from_bytes(xy[:2], 'little') len_x = int.from_bytes(xy[:2], "little")
x = xy[2:len_x+2] x = xy[2 : len_x + 2]
y = xy[len_x+2:] y = xy[len_x + 2 :]
return x, y return x, y
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Program to perform operations using ChaCha20 cipher on files", description="Program to perform operations using ChaCha20 cipher on files",
@ -121,7 +140,9 @@ def main():
subparsers = parser.add_subparsers(dest="operation", help="Operation to perform") subparsers = parser.add_subparsers(dest="operation", help="Operation to perform")
# Setup subcommand # Setup subcommand
setup_parser = subparsers.add_parser("setup", help="Setup diffie helman key pair for user") setup_parser = subparsers.add_parser(
"setup", help="Setup diffie helman key pair for user"
)
setup_parser.add_argument("user", help="User for which to setup the key pair") setup_parser.add_argument("user", help="User for which to setup the key pair")
# Encrypt subcommand # Encrypt subcommand
@ -142,11 +163,12 @@ def main():
case "enc": case "enc":
user = args.user user = args.user
file = args.file file = args.file
encrypt(user,file) encrypt(user, file)
case "dec": case "dec":
user = args.user user = args.user
file = args.file file = args.file
decrypt(user,file) decrypt(user, file)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

8
TPs/TP04/input Normal file
View file

@ -0,0 +1,8 @@
As armas e os barões assinalados,
Que da ocidental praia Lusitana,
Por mares nunca de antes navegados,
Passaram ainda além da Taprobana,
Em perigos e guerras esforçados,
Mais do que prometia a força humana,
E entre gente remota edificaram
Novo Reino, que tanto sublimaram;