diff --git a/TPs/TP04/cfich_nike.py b/TPs/TP04/cfich_nike.py index beeafb9..d04e296 100644 --- a/TPs/TP04/cfich_nike.py +++ b/TPs/TP04/cfich_nike.py @@ -1,11 +1,11 @@ import argparse import os +import cryptography.hazmat.primitives.serialization as serialization from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import dh from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 from cryptography.hazmat.primitives.kdf.hkdf import HKDF -import cryptography.hazmat.primitives.serialization as serialization from cryptography.hazmat.primitives.serialization import ( Encoding, NoEncryption, @@ -13,106 +13,125 @@ from cryptography.hazmat.primitives.serialization import ( PublicFormat, ) +p = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF +g = 2 +params = dh.DHParameterNumbers(p, g).parameters() + def setup(user): - parameters = dh.generate_parameters(generator=2, key_size=512) - private_key = parameters.generate_private_key() + private_key = params.generate_private_key() public_key = private_key.public_key() - skey = open(f"{user}.sk", 'wb') - pkey = open(f"{user}.pk", 'wb') - skey.write(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 = open(f"{user}.sk", "wb") + pkey = open(f"{user}.pk", "wb") + skey.write( + 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() pkey.close() -def encrypt(user,filename): - peer_pkey_file = open(f"{user}.pk", 'rb') +def encrypt(user, filename): + peer_pkey_file = open(f"{user}.pk", "rb") if peer_pkey_file is None: print(f"No public key found for {user}") return - file_r = open(filename, 'rb') + file_r = open(filename, "rb") if file_r is None: print(f"File {filename} not found") return - # FIX: Add try - parameters = dh.generate_parameters(generator=2, key_size=512) - skey = parameters.generate_private_key() - peer_pkey= serialization.load_pem_public_key(peer_pkey_file.read()) - 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: + + skey = params.generate_private_key() + peer_pkey = serialization.load_pem_public_key(peer_pkey_file.read()) + if not isinstance(peer_pkey, dh.DHPublicKey): print("Error: Invalid key type") 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() chacha = ChaCha20Poly1305(derived_key) nonce = os.urandom(12) ciphertext = chacha.encrypt(nonce, message, None) - file_w = open(f"{filename}.enc", 'wb') - nonce_ciphertext = mkpair(nonce, ciphertext) - to_send = mkpair(peer_pkey.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo), nonce_ciphertext) + file_w = open(f"{filename}.enc", "wb") + nonce_ciphertext = 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_r.close() file_w.close() - skey_file.close() peer_pkey_file.close() -def decrypt(user,filename): - skey_file = open(f"{user}.sk", 'rb') +def decrypt(user, filename): + skey_file = open(f"{user}.sk", "rb") if skey_file is None: print(f"No private key found for {user}") return - file_r = open(filename, 'rb') + file_r = open(filename, "rb") if file_r is None: print(f"File {filename} not found") return message_bytes = file_r.read() peer_pkey_bytes, ciphertext = unpair(message_bytes) - # FIX: Add try - skey = serialization.load_pem_private_key(skey_file.read(), None) - peer_pkey = serialization.load_pem_public_key(peer_pkey_bytes) - derived_key = None - if isinstance(skey, dh.DHPrivateKey) and 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: + + skey = serialization.load_pem_private_key(skey_file.read(), None) + peer_pkey = serialization.load_der_public_key(peer_pkey_bytes) + if not isinstance(skey, dh.DHPrivateKey) or not isinstance( + peer_pkey, dh.DHPublicKey + ): print("Error: Invalid key type") 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) 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_r.close() file_w.close() skey_file.close() - - 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_bytes = len_x.to_bytes(2, 'little') + len_x_bytes = len_x.to_bytes(2, "little") return len_x_bytes + x + y + def unpair(xy): - """ extrai componentes de um par codificado com 'mkpair' """ - len_x = int.from_bytes(xy[:2], 'little') - x = xy[2:len_x+2] - y = xy[len_x+2:] + """extrai componentes de um par codificado com 'mkpair'""" + len_x = int.from_bytes(xy[:2], "little") + x = xy[2 : len_x + 2] + y = xy[len_x + 2 :] return x, y + def main(): parser = argparse.ArgumentParser( 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") # 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") # Encrypt subcommand @@ -142,11 +163,12 @@ def main(): case "enc": user = args.user file = args.file - encrypt(user,file) + encrypt(user, file) case "dec": user = args.user file = args.file - decrypt(user,file) + decrypt(user, file) + if __name__ == "__main__": main() diff --git a/TPs/TP04/input b/TPs/TP04/input new file mode 100644 index 0000000..badaeeb --- /dev/null +++ b/TPs/TP04/input @@ -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;