From 36f754e266f507203177a2b30ed55e79bf9623f8 Mon Sep 17 00:00:00 2001 From: vernuser Date: Tue, 10 Dec 2024 08:47:33 +0800 Subject: [PATCH 01/11] Initial commit --- .idea/.gitignore | 8 +++++ .../inspectionProfiles/profiles_settings.xml | 6 ++++ .idea/material_theme_project_new.xml | 10 ++++++ .idea/misc.xml | 4 +++ .idea/modules.xml | 8 +++++ .idea/vcs.xml | 4 +++ .idea/应用密码学课设.iml | 8 +++++ encryption_utils.py | 34 ++++++++++++++++++ example.txt | 2 ++ receiver.py | 31 ++++++++++++++++ run_example.py | 35 +++++++++++++++++++ sender.py | 25 +++++++++++++ 12 files changed, 175 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/material_theme_project_new.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/应用密码学课设.iml create mode 100644 encryption_utils.py create mode 100644 example.txt create mode 100644 receiver.py create mode 100644 run_example.py create mode 100644 sender.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..a7cdac7 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/material_theme_project_new.xml b/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..579b55b --- /dev/null +++ b/.idea/material_theme_project_new.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5403b9e --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f51b2be --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..d843f34 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/应用密码学课设.iml b/.idea/应用密码学课设.iml new file mode 100644 index 0000000..a80cbb1 --- /dev/null +++ b/.idea/应用密码学课设.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/encryption_utils.py b/encryption_utils.py new file mode 100644 index 0000000..3b70510 --- /dev/null +++ b/encryption_utils.py @@ -0,0 +1,34 @@ +from Crypto.PublicKey import RSA +from Crypto.Cipher import PKCS1_OAEP, AES +from Crypto.Random import get_random_bytes + + +class AsymmetricEncryption: + def __init__(self): + self.key_pair = RSA.generate(2048) + + def get_public_key(self): + return self.key_pair.publickey() + + def get_private_key(self): + return self.key_pair + + def encrypt_with_public_key(self, data, public_key): + cipher_rsa = PKCS1_OAEP.new(public_key) + return cipher_rsa.encrypt(data) + + def decrypt_with_private_key(self, encrypted_data): + cipher_rsa = PKCS1_OAEP.new(self.key_pair) + return cipher_rsa.decrypt(encrypted_data) + + +class SymmetricEncryption: + def encrypt(self, data, key): + cipher_aes = AES.new(key, AES.MODE_GCM) + nonce = cipher_aes.nonce + ciphertext, tag = cipher_aes.encrypt_and_digest(data) + return nonce, ciphertext, tag + + def decrypt(self, nonce, ciphertext, tag, key): + cipher_aes = AES.new(key, AES.MODE_GCM, nonce=nonce) + return cipher_aes.decrypt_and_verify(ciphertext, tag) diff --git a/example.txt b/example.txt new file mode 100644 index 0000000..a47e663 --- /dev/null +++ b/example.txt @@ -0,0 +1,2 @@ +123456 +adgjl \ No newline at end of file diff --git a/receiver.py b/receiver.py new file mode 100644 index 0000000..9ed9cf5 --- /dev/null +++ b/receiver.py @@ -0,0 +1,31 @@ +import base64 +from encryption_utils import SymmetricEncryption, AsymmetricEncryption, calculate_file_hash + +class Receiver: + def __init__(self, private_key): + self.private_key = private_key + + def receive_file(self, encoded_data_packet): + decoded_data_packet = base64.b64decode(encoded_data_packet) + + nonce = decoded_data_packet[:16] + ciphertext = decoded_data_packet[16:-256-64] + tag = decoded_data_packet[-256-64:-256] + encrypted_symmetric_key = decoded_data_packet[-256:] + original_hash = decoded_data_packet[-256-64:-256] # 保持为字节 + + asymmetric_encryption = AsymmetricEncryption() + decrypted_symmetric_key = asymmetric_encryption.decrypt_with_private_key(encrypted_symmetric_key) + + symmetric_encryption = SymmetricEncryption() + decrypted_file_data = symmetric_encryption.decrypt(nonce, ciphertext, tag, decrypted_symmetric_key) + + # Recalculate hash of decrypted file data + received_file_hash = calculate_file_hash(decrypted_file_data).encode() + + if received_file_hash == original_hash: + print("文件传输成功,文件完整性验证通过。") + else: + print("文件传输失败,文件可能已被篡改。") + + return decrypted_file_data diff --git a/run_example.py b/run_example.py new file mode 100644 index 0000000..520728a --- /dev/null +++ b/run_example.py @@ -0,0 +1,35 @@ +from encryption_utils import AsymmetricEncryption, SymmetricEncryption +from Crypto.Random import get_random_bytes + +def run_example(): + # 生成接收方的密钥对 + receiver_asymmetric = AsymmetricEncryption() + receiver_public_key = receiver_asymmetric.get_public_key() + receiver_private_key = receiver_asymmetric.get_private_key() + + # 生成对称密钥 + symmetric_key = get_random_bytes(16) # AES 128 位密钥 + + # 使用接收方的公钥加密对称密钥 + encrypted_symmetric_key = receiver_asymmetric.encrypt_with_public_key(symmetric_key, receiver_public_key) + + # 读取文件内容 + with open('example.txt', 'rb') as file: + file_data = file.read() + + # 使用对称密钥加密文件内容 + symmetric_encryption = SymmetricEncryption() + nonce, ciphertext, tag = symmetric_encryption.encrypt(file_data, symmetric_key) + + # 模拟发送和接收 + encoded_packet = (encrypted_symmetric_key, nonce, ciphertext, tag) + + # 使用接收方私钥解密对称密钥 + decrypted_symmetric_key = receiver_asymmetric.decrypt_with_private_key(encoded_packet[0]) + + # 使用解密后的对称密钥解密文件内容 + decrypted_data = symmetric_encryption.decrypt(encoded_packet[1], encoded_packet[2], encoded_packet[3], decrypted_symmetric_key) + print("Decrypted Data:", decrypted_data.decode('utf-8')) + +if __name__ == "__main__": + run_example() diff --git a/sender.py b/sender.py new file mode 100644 index 0000000..afcb64d --- /dev/null +++ b/sender.py @@ -0,0 +1,25 @@ +import base64 +from Crypto.Random import get_random_bytes # 确保导入随机字节生成函数 +from encryption_utils import SymmetricEncryption, AsymmetricEncryption, calculate_file_hash + +class Sender: + def __init__(self, filepath, receiver_public_key): + self.filepath = filepath + self.receiver_public_key = receiver_public_key + + def send_file(self): + with open(self.filepath, 'rb') as f: + file_data = f.read() + + symmetric_key = get_random_bytes(16) + symmetric_encryption = SymmetricEncryption() + nonce, ciphertext, tag = symmetric_encryption.encrypt(file_data, symmetric_key) + + file_hash = calculate_file_hash(file_data) + + asymmetric_encryption = AsymmetricEncryption() + encrypted_symmetric_key = asymmetric_encryption.encrypt_with_public_key(symmetric_key, self.receiver_public_key) + + encoded_data_packet = base64.b64encode(nonce + ciphertext + tag + encrypted_symmetric_key + file_hash.encode()) + + return encoded_data_packet -- 2.34.1 From 772622a1a6291b8abb1d9059a048fa0355ad2708 Mon Sep 17 00:00:00 2001 From: vernuser Date: Tue, 10 Dec 2024 09:17:41 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E5=8A=A0=E4=BA=86=E4=BA=92=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 3 ++ .idea/vcs.xml | 4 ++- encryption_utils.py | 7 ++-- example.txt | 2 +- file_transfer.py | 78 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 file_transfer.py diff --git a/.idea/misc.xml b/.idea/misc.xml index 5403b9e..f8a22e9 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,7 @@ + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index d843f34..94a25f7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,4 +1,6 @@ - + + + \ No newline at end of file diff --git a/encryption_utils.py b/encryption_utils.py index 3b70510..92f0d6b 100644 --- a/encryption_utils.py +++ b/encryption_utils.py @@ -1,7 +1,7 @@ from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP, AES from Crypto.Random import get_random_bytes - +from Crypto.Hash import SHA256 class AsymmetricEncryption: def __init__(self): @@ -21,7 +21,6 @@ class AsymmetricEncryption: cipher_rsa = PKCS1_OAEP.new(self.key_pair) return cipher_rsa.decrypt(encrypted_data) - class SymmetricEncryption: def encrypt(self, data, key): cipher_aes = AES.new(key, AES.MODE_GCM) @@ -32,3 +31,7 @@ class SymmetricEncryption: def decrypt(self, nonce, ciphertext, tag, key): cipher_aes = AES.new(key, AES.MODE_GCM, nonce=nonce) return cipher_aes.decrypt_and_verify(ciphertext, tag) + +def calculate_file_hash(file_data): + hash_obj = SHA256.new(file_data) + return hash_obj.digest() diff --git a/example.txt b/example.txt index a47e663..76b02a3 100644 --- a/example.txt +++ b/example.txt @@ -1,2 +1,2 @@ 123456 -adgjl \ No newline at end of file +asdfghjkl \ No newline at end of file diff --git a/file_transfer.py b/file_transfer.py new file mode 100644 index 0000000..b6b664f --- /dev/null +++ b/file_transfer.py @@ -0,0 +1,78 @@ +import socket +import threading +from Crypto.PublicKey import RSA +from Crypto.Cipher import AES, PKCS1_OAEP +from Crypto.Random import get_random_bytes +from Crypto.Hash import SHA256 + +class FileTransferApp: + def __init__(self, host, port): + self.host = host + self.port = port + self.private_key = None + self.public_key = None + self.running = True + + def generate_keys(self): + key = RSA.generate(2048) + self.private_key = key.export_key() + self.public_key = key.publickey().export_key() + + def send_file(self, filepath, receiver_host): + try: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((receiver_host, self.port)) + sender = Sender(filepath, receiver_public_key=self.public_key) + data_to_send = sender.send_file() + s.sendall(data_to_send) + print("File sent successfully.") + except Exception as e: + print(f"An error occurred while sending the file: {e}") + + def receive_file(self): + try: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind((self.host, self.port)) + s.listen() + print(f"Server listening on {self.host}:{self.port}") + conn, addr = s.accept() + with conn: + print(f"Connected by {addr}") + data = b'' + while True: + packet = conn.recv(1024) + if not packet: + break + data += packet + receiver = Receiver(private_key=self.private_key) + decrypted_data = receiver.receive_file(data) + if decrypted_data: + # Save or process the decrypted file data + with open('received_file', 'wb') as f: + f.write(decrypted_data) + print("File received and decrypted successfully.") + except Exception as e: + print(f"An error occurred while receiving the file: {e}") + + def run(self): + while self.running: + command = input("Enter 'generate_keys' to generate keys, 'send' to send a file, 'receive' to receive a file, or 'exit' to quit: ").strip().lower() + if command == 'generate_keys': + self.generate_keys() + print("Keys generated successfully.") + elif command == 'send': + filepath = input("Enter the path of the file to send: ") + receiver_host = input("Enter the receiver's host (IP address): ") + threading.Thread(target=self.send_file, args=(filepath, receiver_host)).start() + elif command == 'receive': + threading.Thread(target=self.receive_file).start() + elif command == 'exit': + self.running = False + print("Exiting application.") + break + else: + print("Invalid command.") + +if __name__ == "__main__": + app = FileTransferApp(host='0.0.0.0', port=65432) + app.run() -- 2.34.1 From 16e44383797d0a4f48d146908d66387043bd625d Mon Sep 17 00:00:00 2001 From: vernuser Date: Tue, 10 Dec 2024 11:25:55 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E5=8A=A0=E4=BA=86=E4=B8=AD=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- file_transfer.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/file_transfer.py b/file_transfer.py index b6b664f..7100c26 100644 --- a/file_transfer.py +++ b/file_transfer.py @@ -5,6 +5,7 @@ from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.Random import get_random_bytes from Crypto.Hash import SHA256 + class FileTransferApp: def __init__(self, host, port): self.host = host @@ -17,6 +18,7 @@ class FileTransferApp: key = RSA.generate(2048) self.private_key = key.export_key() self.public_key = key.publickey().export_key() + print("密钥生成成功。") def send_file(self, filepath, receiver_host): try: @@ -25,19 +27,19 @@ class FileTransferApp: sender = Sender(filepath, receiver_public_key=self.public_key) data_to_send = sender.send_file() s.sendall(data_to_send) - print("File sent successfully.") + print("文件发送成功。") except Exception as e: - print(f"An error occurred while sending the file: {e}") + print(f"发送文件时发生错误: {e}") def receive_file(self): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((self.host, self.port)) s.listen() - print(f"Server listening on {self.host}:{self.port}") + print(f"服务器正在监听 {self.host}:{self.port}") conn, addr = s.accept() with conn: - print(f"Connected by {addr}") + print(f"已连接 {addr}") data = b'' while True: packet = conn.recv(1024) @@ -47,31 +49,30 @@ class FileTransferApp: receiver = Receiver(private_key=self.private_key) decrypted_data = receiver.receive_file(data) if decrypted_data: - # Save or process the decrypted file data + # 保存或处理解密后的文件数据 with open('received_file', 'wb') as f: f.write(decrypted_data) - print("File received and decrypted successfully.") + print("文件接收并解密成功。") except Exception as e: - print(f"An error occurred while receiving the file: {e}") + print(f"接收文件时发生错误: {e}") def run(self): while self.running: - command = input("Enter 'generate_keys' to generate keys, 'send' to send a file, 'receive' to receive a file, or 'exit' to quit: ").strip().lower() + command = input("输入 'generate_keys' 生成密钥,'send' 发送文件,'receive' 接收文件,或 'exit' 退出程序: ").strip().lower() if command == 'generate_keys': self.generate_keys() - print("Keys generated successfully.") elif command == 'send': - filepath = input("Enter the path of the file to send: ") - receiver_host = input("Enter the receiver's host (IP address): ") + filepath = input("输入要发送的文件路径: ") + receiver_host = input("输入接收方的计算机IP地址: ") threading.Thread(target=self.send_file, args=(filepath, receiver_host)).start() elif command == 'receive': threading.Thread(target=self.receive_file).start() elif command == 'exit': self.running = False - print("Exiting application.") + print("正在退出程序。") break else: - print("Invalid command.") + print("无效的命令。") if __name__ == "__main__": app = FileTransferApp(host='0.0.0.0', port=65432) -- 2.34.1 From 45f7cbb9630f788b067690dc8ab53db0920288d2 Mon Sep 17 00:00:00 2001 From: vernuser Date: Tue, 10 Dec 2024 14:06:27 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E7=AD=BE=E5=90=8D=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 - .../inspectionProfiles/profiles_settings.xml | 6 - .idea/material_theme_project_new.xml | 10 -- .idea/misc.xml | 7 - .idea/modules.xml | 8 - .idea/vcs.xml | 6 - .idea/应用密码学课设.iml | 8 - 1.txt | 1 + encryption_utils.py | 20 ++- example.txt | 2 - file_transfer.py | 101 +++++++++--- receiver.py | 53 +++--- run_example.py | 153 +++++++++++++++--- sender.py | 36 +++-- 14 files changed, 273 insertions(+), 146 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/material_theme_project_new.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/应用密码学课设.iml create mode 100644 1.txt delete mode 100644 example.txt diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index a7cdac7..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# 默认忽略的文件 -/shelf/ -/workspace.xml -# 基于编辑器的 HTTP 客户端请求 -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/material_theme_project_new.xml b/.idea/material_theme_project_new.xml deleted file mode 100644 index 579b55b..0000000 --- a/.idea/material_theme_project_new.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index f8a22e9..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index f51b2be..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/应用密码学课设.iml b/.idea/应用密码学课设.iml deleted file mode 100644 index a80cbb1..0000000 --- a/.idea/应用密码学课设.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/1.txt b/1.txt new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/1.txt @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/encryption_utils.py b/encryption_utils.py index 92f0d6b..4a916a7 100644 --- a/encryption_utils.py +++ b/encryption_utils.py @@ -1,6 +1,7 @@ from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP, AES from Crypto.Random import get_random_bytes +from Crypto.Signature import pkcs1_15 from Crypto.Hash import SHA256 class AsymmetricEncryption: @@ -21,6 +22,19 @@ class AsymmetricEncryption: cipher_rsa = PKCS1_OAEP.new(self.key_pair) return cipher_rsa.decrypt(encrypted_data) + def sign_data(self, data): + h = SHA256.new(data) + signature = pkcs1_15.new(self.key_pair).sign(h) + return signature + + def verify_signature(self, data, signature, public_key): + h = SHA256.new(data) + try: + pkcs1_15.new(public_key).verify(h, signature) + return True + except (ValueError, TypeError): + return False + class SymmetricEncryption: def encrypt(self, data, key): cipher_aes = AES.new(key, AES.MODE_GCM) @@ -30,8 +44,4 @@ class SymmetricEncryption: def decrypt(self, nonce, ciphertext, tag, key): cipher_aes = AES.new(key, AES.MODE_GCM, nonce=nonce) - return cipher_aes.decrypt_and_verify(ciphertext, tag) - -def calculate_file_hash(file_data): - hash_obj = SHA256.new(file_data) - return hash_obj.digest() + return cipher_aes.decrypt_and_verify(ciphertext, tag) \ No newline at end of file diff --git a/example.txt b/example.txt deleted file mode 100644 index 76b02a3..0000000 --- a/example.txt +++ /dev/null @@ -1,2 +0,0 @@ -123456 -asdfghjkl \ No newline at end of file diff --git a/file_transfer.py b/file_transfer.py index 7100c26..2c9bfaa 100644 --- a/file_transfer.py +++ b/file_transfer.py @@ -1,15 +1,14 @@ import socket import threading from Crypto.PublicKey import RSA -from Crypto.Cipher import AES, PKCS1_OAEP -from Crypto.Random import get_random_bytes -from Crypto.Hash import SHA256 - +from sender import Sender +from receiver import Receiver class FileTransferApp: - def __init__(self, host, port): + def __init__(self, host, port, role): self.host = host self.port = port + self.role = role self.private_key = None self.public_key = None self.running = True @@ -18,55 +17,114 @@ class FileTransferApp: key = RSA.generate(2048) self.private_key = key.export_key() self.public_key = key.publickey().export_key() - print("密钥生成成功。") + if self.role == 'sender': + priv_filename = 'send_private.pem' + pub_filename = 'send_public.pem' + else: + priv_filename = 'receive_private.pem' + pub_filename = 'receive_public.pem' + with open(priv_filename, 'wb') as priv_file: + priv_file.write(self.private_key) + with open(pub_filename, 'wb') as pub_file: + pub_file.write(self.public_key) + print(f"密钥生成成功,已保存到 {priv_filename} 和 {pub_filename}。") + + def load_keys(self): + if self.role == 'sender': + priv_filename = 'send_private.pem' + pub_filename = 'send_public.pem' + else: + priv_filename = 'receive_private.pem' + pub_filename = 'receive_public.pem' + try: + with open(priv_filename, 'rb') as priv_file: + self.private_key = priv_file.read() + with open(pub_filename, 'rb') as pub_file: + self.public_key = pub_file.read() + print("密钥加载成功。") + except FileNotFoundError: + print("密钥文件未找到,请先生成密钥。") + + def load_public_key(self, filepath): + try: + with open(filepath, 'rb') as pub_file: + return pub_file.read() + except FileNotFoundError: + print(f"公钥文件 {filepath} 未找到。") + return None + + def send_file(self, filepath, receiver_host, receiver_public_key_path): + receiver_public_key = self.load_public_key(receiver_public_key_path) + if receiver_public_key is None: + return - def send_file(self, filepath, receiver_host): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((receiver_host, self.port)) - sender = Sender(filepath, receiver_public_key=self.public_key) + + sender = Sender(filepath, receiver_public_key, self.private_key) data_to_send = sender.send_file() - s.sendall(data_to_send) + if data_to_send is None: + print("文件加密失败,未发送。") + return + + s.sendall(data_to_send.encode()) print("文件发送成功。") except Exception as e: print(f"发送文件时发生错误: {e}") - def receive_file(self): + def receive_file(self, sender_public_key_path): + sender_public_key = self.load_public_key(sender_public_key_path) + if sender_public_key is None: + return + try: + if self.private_key is None: + raise ValueError("未生成私钥,请先生成密钥。") + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((self.host, self.port)) s.listen() - print(f"服务器正在监听 {self.host}:{self.port}") + print(f"服务器正在 {self.host}:{self.port} 监听...") conn, addr = s.accept() with conn: - print(f"已连接 {addr}") + print(f"已连接到 {addr}") data = b'' while True: packet = conn.recv(1024) if not packet: break data += packet - receiver = Receiver(private_key=self.private_key) - decrypted_data = receiver.receive_file(data) - if decrypted_data: - # 保存或处理解密后的文件数据 + + receiver = Receiver(self.private_key, sender_public_key) + decrypted_data = receiver.receive_file(data.decode()) + + if decrypted_data is not None: with open('received_file', 'wb') as f: f.write(decrypted_data) print("文件接收并解密成功。") + else: + print("解密失败,文件未保存。") + except ValueError as ve: + print(f"值错误: {ve}") except Exception as e: print(f"接收文件时发生错误: {e}") def run(self): while self.running: - command = input("输入 'generate_keys' 生成密钥,'send' 发送文件,'receive' 接收文件,或 'exit' 退出程序: ").strip().lower() + command = input("输入 'generate_keys' 生成密钥,'load_keys' 加载密钥,'send' 发送文件,'receive' 接收文件,或 'exit' 退出程序: ").strip().lower() if command == 'generate_keys': self.generate_keys() + elif command == 'load_keys': + self.load_keys() elif command == 'send': filepath = input("输入要发送的文件路径: ") receiver_host = input("输入接收方的计算机IP地址: ") - threading.Thread(target=self.send_file, args=(filepath, receiver_host)).start() + receiver_public_key_path = input("输入接收方的公钥文件路径: ") + threading.Thread(target=self.send_file, args=(filepath, receiver_host, receiver_public_key_path)).start() elif command == 'receive': - threading.Thread(target=self.receive_file).start() + sender_public_key_path = input("输入发送方的公钥文件路径: ") + threading.Thread(target=self.receive_file, args=(sender_public_key_path,)).start() elif command == 'exit': self.running = False print("正在退出程序。") @@ -75,5 +133,6 @@ class FileTransferApp: print("无效的命令。") if __name__ == "__main__": - app = FileTransferApp(host='0.0.0.0', port=65432) - app.run() + role = input("输入角色 ('sender' 或 'receiver'): ").strip().lower() + app = FileTransferApp(host='0.0.0.0', port=65432, role=role) + app.run() \ No newline at end of file diff --git a/receiver.py b/receiver.py index 9ed9cf5..2865b7c 100644 --- a/receiver.py +++ b/receiver.py @@ -1,31 +1,30 @@ +from Crypto.Cipher import AES, PKCS1_OAEP +from Crypto.PublicKey import RSA +import json import base64 -from encryption_utils import SymmetricEncryption, AsymmetricEncryption, calculate_file_hash +from encryption_utils import AsymmetricEncryption, SymmetricEncryption class Receiver: - def __init__(self, private_key): - self.private_key = private_key - - def receive_file(self, encoded_data_packet): - decoded_data_packet = base64.b64decode(encoded_data_packet) - - nonce = decoded_data_packet[:16] - ciphertext = decoded_data_packet[16:-256-64] - tag = decoded_data_packet[-256-64:-256] - encrypted_symmetric_key = decoded_data_packet[-256:] - original_hash = decoded_data_packet[-256-64:-256] # 保持为字节 - - asymmetric_encryption = AsymmetricEncryption() - decrypted_symmetric_key = asymmetric_encryption.decrypt_with_private_key(encrypted_symmetric_key) - - symmetric_encryption = SymmetricEncryption() - decrypted_file_data = symmetric_encryption.decrypt(nonce, ciphertext, tag, decrypted_symmetric_key) - - # Recalculate hash of decrypted file data - received_file_hash = calculate_file_hash(decrypted_file_data).encode() - - if received_file_hash == original_hash: - print("文件传输成功,文件完整性验证通过。") + def __init__(self, private_key, sender_public_key): + self.private_key = RSA.import_key(private_key) + self.sender_public_key = RSA.import_key(sender_public_key) + self.asym_enc = AsymmetricEncryption() + self.sym_enc = SymmetricEncryption() + + def receive_file(self, data): + data = json.loads(data) + enc_session_key = base64.b64decode(data['enc_session_key']) + nonce = base64.b64decode(data['nonce']) + tag = base64.b64decode(data['tag']) + ciphertext = base64.b64decode(data['ciphertext']) + signature = base64.b64decode(data['signature']) + + cipher_rsa = PKCS1_OAEP.new(self.private_key) + session_key = cipher_rsa.decrypt(enc_session_key) + + file_data = self.sym_enc.decrypt(nonce, ciphertext, tag, session_key) + + if self.asym_enc.verify_signature(file_data, signature, self.sender_public_key): + return file_data else: - print("文件传输失败,文件可能已被篡改。") - - return decrypted_file_data + raise ValueError("签名验证失败") \ No newline at end of file diff --git a/run_example.py b/run_example.py index 520728a..2c9bfaa 100644 --- a/run_example.py +++ b/run_example.py @@ -1,35 +1,138 @@ -from encryption_utils import AsymmetricEncryption, SymmetricEncryption -from Crypto.Random import get_random_bytes +import socket +import threading +from Crypto.PublicKey import RSA +from sender import Sender +from receiver import Receiver -def run_example(): - # 生成接收方的密钥对 - receiver_asymmetric = AsymmetricEncryption() - receiver_public_key = receiver_asymmetric.get_public_key() - receiver_private_key = receiver_asymmetric.get_private_key() +class FileTransferApp: + def __init__(self, host, port, role): + self.host = host + self.port = port + self.role = role + self.private_key = None + self.public_key = None + self.running = True - # 生成对称密钥 - symmetric_key = get_random_bytes(16) # AES 128 位密钥 + def generate_keys(self): + key = RSA.generate(2048) + self.private_key = key.export_key() + self.public_key = key.publickey().export_key() + if self.role == 'sender': + priv_filename = 'send_private.pem' + pub_filename = 'send_public.pem' + else: + priv_filename = 'receive_private.pem' + pub_filename = 'receive_public.pem' + with open(priv_filename, 'wb') as priv_file: + priv_file.write(self.private_key) + with open(pub_filename, 'wb') as pub_file: + pub_file.write(self.public_key) + print(f"密钥生成成功,已保存到 {priv_filename} 和 {pub_filename}。") - # 使用接收方的公钥加密对称密钥 - encrypted_symmetric_key = receiver_asymmetric.encrypt_with_public_key(symmetric_key, receiver_public_key) + def load_keys(self): + if self.role == 'sender': + priv_filename = 'send_private.pem' + pub_filename = 'send_public.pem' + else: + priv_filename = 'receive_private.pem' + pub_filename = 'receive_public.pem' + try: + with open(priv_filename, 'rb') as priv_file: + self.private_key = priv_file.read() + with open(pub_filename, 'rb') as pub_file: + self.public_key = pub_file.read() + print("密钥加载成功。") + except FileNotFoundError: + print("密钥文件未找到,请先生成密钥。") - # 读取文件内容 - with open('example.txt', 'rb') as file: - file_data = file.read() + def load_public_key(self, filepath): + try: + with open(filepath, 'rb') as pub_file: + return pub_file.read() + except FileNotFoundError: + print(f"公钥文件 {filepath} 未找到。") + return None - # 使用对称密钥加密文件内容 - symmetric_encryption = SymmetricEncryption() - nonce, ciphertext, tag = symmetric_encryption.encrypt(file_data, symmetric_key) + def send_file(self, filepath, receiver_host, receiver_public_key_path): + receiver_public_key = self.load_public_key(receiver_public_key_path) + if receiver_public_key is None: + return - # 模拟发送和接收 - encoded_packet = (encrypted_symmetric_key, nonce, ciphertext, tag) + try: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((receiver_host, self.port)) - # 使用接收方私钥解密对称密钥 - decrypted_symmetric_key = receiver_asymmetric.decrypt_with_private_key(encoded_packet[0]) + sender = Sender(filepath, receiver_public_key, self.private_key) + data_to_send = sender.send_file() + if data_to_send is None: + print("文件加密失败,未发送。") + return - # 使用解密后的对称密钥解密文件内容 - decrypted_data = symmetric_encryption.decrypt(encoded_packet[1], encoded_packet[2], encoded_packet[3], decrypted_symmetric_key) - print("Decrypted Data:", decrypted_data.decode('utf-8')) + s.sendall(data_to_send.encode()) + print("文件发送成功。") + except Exception as e: + print(f"发送文件时发生错误: {e}") + + def receive_file(self, sender_public_key_path): + sender_public_key = self.load_public_key(sender_public_key_path) + if sender_public_key is None: + return + + try: + if self.private_key is None: + raise ValueError("未生成私钥,请先生成密钥。") + + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind((self.host, self.port)) + s.listen() + print(f"服务器正在 {self.host}:{self.port} 监听...") + conn, addr = s.accept() + with conn: + print(f"已连接到 {addr}") + data = b'' + while True: + packet = conn.recv(1024) + if not packet: + break + data += packet + + receiver = Receiver(self.private_key, sender_public_key) + decrypted_data = receiver.receive_file(data.decode()) + + if decrypted_data is not None: + with open('received_file', 'wb') as f: + f.write(decrypted_data) + print("文件接收并解密成功。") + else: + print("解密失败,文件未保存。") + except ValueError as ve: + print(f"值错误: {ve}") + except Exception as e: + print(f"接收文件时发生错误: {e}") + + def run(self): + while self.running: + command = input("输入 'generate_keys' 生成密钥,'load_keys' 加载密钥,'send' 发送文件,'receive' 接收文件,或 'exit' 退出程序: ").strip().lower() + if command == 'generate_keys': + self.generate_keys() + elif command == 'load_keys': + self.load_keys() + elif command == 'send': + filepath = input("输入要发送的文件路径: ") + receiver_host = input("输入接收方的计算机IP地址: ") + receiver_public_key_path = input("输入接收方的公钥文件路径: ") + threading.Thread(target=self.send_file, args=(filepath, receiver_host, receiver_public_key_path)).start() + elif command == 'receive': + sender_public_key_path = input("输入发送方的公钥文件路径: ") + threading.Thread(target=self.receive_file, args=(sender_public_key_path,)).start() + elif command == 'exit': + self.running = False + print("正在退出程序。") + break + else: + print("无效的命令。") if __name__ == "__main__": - run_example() + role = input("输入角色 ('sender' 或 'receiver'): ").strip().lower() + app = FileTransferApp(host='0.0.0.0', port=65432, role=role) + app.run() \ No newline at end of file diff --git a/sender.py b/sender.py index afcb64d..4ac039a 100644 --- a/sender.py +++ b/sender.py @@ -1,25 +1,35 @@ +from Crypto.Cipher import AES, PKCS1_OAEP +from Crypto.Random import get_random_bytes +from Crypto.PublicKey import RSA +import json import base64 -from Crypto.Random import get_random_bytes # 确保导入随机字节生成函数 -from encryption_utils import SymmetricEncryption, AsymmetricEncryption, calculate_file_hash +from encryption_utils import AsymmetricEncryption, SymmetricEncryption class Sender: - def __init__(self, filepath, receiver_public_key): + def __init__(self, filepath, receiver_public_key, sender_private_key): self.filepath = filepath - self.receiver_public_key = receiver_public_key + self.receiver_public_key = RSA.import_key(receiver_public_key) + self.sender_private_key = RSA.import_key(sender_private_key) + self.asym_enc = AsymmetricEncryption() + self.sym_enc = SymmetricEncryption() def send_file(self): with open(self.filepath, 'rb') as f: file_data = f.read() - symmetric_key = get_random_bytes(16) - symmetric_encryption = SymmetricEncryption() - nonce, ciphertext, tag = symmetric_encryption.encrypt(file_data, symmetric_key) + session_key = get_random_bytes(16) + cipher_rsa = PKCS1_OAEP.new(self.receiver_public_key) + enc_session_key = cipher_rsa.encrypt(session_key) - file_hash = calculate_file_hash(file_data) + nonce, ciphertext, tag = self.sym_enc.encrypt(file_data, session_key) + signature = self.asym_enc.sign_data(file_data) - asymmetric_encryption = AsymmetricEncryption() - encrypted_symmetric_key = asymmetric_encryption.encrypt_with_public_key(symmetric_key, self.receiver_public_key) + data_to_send = { + 'enc_session_key': base64.b64encode(enc_session_key).decode(), + 'nonce': base64.b64encode(nonce).decode(), + 'tag': base64.b64encode(tag).decode(), + 'ciphertext': base64.b64encode(ciphertext).decode(), + 'signature': base64.b64encode(signature).decode() + } - encoded_data_packet = base64.b64encode(nonce + ciphertext + tag + encrypted_symmetric_key + file_hash.encode()) - - return encoded_data_packet + return json.dumps(data_to_send) \ No newline at end of file -- 2.34.1 From ebd59a33e5af17b7b835594a40af0957bc70ab6d Mon Sep 17 00:00:00 2001 From: vernuser Date: Tue, 10 Dec 2024 15:30:22 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E5=B7=B2=E6=88=90=E5=8A=9F=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E8=99=9A=E6=8B=9F=E6=9C=BA=E5=92=8C=E7=89=A9?= =?UTF-8?q?=E7=90=86=E6=9C=BA=E4=B9=8B=E9=97=B4=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- file_transfer.py | 138 ----------------------------------------------- generate_key.py | 9 ++++ receiver.py | 81 ++++++++++++++++++---------- run_example.py | 138 ----------------------------------------------- sender.py | 84 +++++++++++++++++------------ server.py | 42 +++++++++++++++ utils.py | 70 ++++++++++++++++++++++++ 7 files changed, 225 insertions(+), 337 deletions(-) delete mode 100644 file_transfer.py create mode 100644 generate_key.py delete mode 100644 run_example.py create mode 100644 server.py create mode 100644 utils.py diff --git a/file_transfer.py b/file_transfer.py deleted file mode 100644 index 2c9bfaa..0000000 --- a/file_transfer.py +++ /dev/null @@ -1,138 +0,0 @@ -import socket -import threading -from Crypto.PublicKey import RSA -from sender import Sender -from receiver import Receiver - -class FileTransferApp: - def __init__(self, host, port, role): - self.host = host - self.port = port - self.role = role - self.private_key = None - self.public_key = None - self.running = True - - def generate_keys(self): - key = RSA.generate(2048) - self.private_key = key.export_key() - self.public_key = key.publickey().export_key() - if self.role == 'sender': - priv_filename = 'send_private.pem' - pub_filename = 'send_public.pem' - else: - priv_filename = 'receive_private.pem' - pub_filename = 'receive_public.pem' - with open(priv_filename, 'wb') as priv_file: - priv_file.write(self.private_key) - with open(pub_filename, 'wb') as pub_file: - pub_file.write(self.public_key) - print(f"密钥生成成功,已保存到 {priv_filename} 和 {pub_filename}。") - - def load_keys(self): - if self.role == 'sender': - priv_filename = 'send_private.pem' - pub_filename = 'send_public.pem' - else: - priv_filename = 'receive_private.pem' - pub_filename = 'receive_public.pem' - try: - with open(priv_filename, 'rb') as priv_file: - self.private_key = priv_file.read() - with open(pub_filename, 'rb') as pub_file: - self.public_key = pub_file.read() - print("密钥加载成功。") - except FileNotFoundError: - print("密钥文件未找到,请先生成密钥。") - - def load_public_key(self, filepath): - try: - with open(filepath, 'rb') as pub_file: - return pub_file.read() - except FileNotFoundError: - print(f"公钥文件 {filepath} 未找到。") - return None - - def send_file(self, filepath, receiver_host, receiver_public_key_path): - receiver_public_key = self.load_public_key(receiver_public_key_path) - if receiver_public_key is None: - return - - try: - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.connect((receiver_host, self.port)) - - sender = Sender(filepath, receiver_public_key, self.private_key) - data_to_send = sender.send_file() - if data_to_send is None: - print("文件加密失败,未发送。") - return - - s.sendall(data_to_send.encode()) - print("文件发送成功。") - except Exception as e: - print(f"发送文件时发生错误: {e}") - - def receive_file(self, sender_public_key_path): - sender_public_key = self.load_public_key(sender_public_key_path) - if sender_public_key is None: - return - - try: - if self.private_key is None: - raise ValueError("未生成私钥,请先生成密钥。") - - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.bind((self.host, self.port)) - s.listen() - print(f"服务器正在 {self.host}:{self.port} 监听...") - conn, addr = s.accept() - with conn: - print(f"已连接到 {addr}") - data = b'' - while True: - packet = conn.recv(1024) - if not packet: - break - data += packet - - receiver = Receiver(self.private_key, sender_public_key) - decrypted_data = receiver.receive_file(data.decode()) - - if decrypted_data is not None: - with open('received_file', 'wb') as f: - f.write(decrypted_data) - print("文件接收并解密成功。") - else: - print("解密失败,文件未保存。") - except ValueError as ve: - print(f"值错误: {ve}") - except Exception as e: - print(f"接收文件时发生错误: {e}") - - def run(self): - while self.running: - command = input("输入 'generate_keys' 生成密钥,'load_keys' 加载密钥,'send' 发送文件,'receive' 接收文件,或 'exit' 退出程序: ").strip().lower() - if command == 'generate_keys': - self.generate_keys() - elif command == 'load_keys': - self.load_keys() - elif command == 'send': - filepath = input("输入要发送的文件路径: ") - receiver_host = input("输入接收方的计算机IP地址: ") - receiver_public_key_path = input("输入接收方的公钥文件路径: ") - threading.Thread(target=self.send_file, args=(filepath, receiver_host, receiver_public_key_path)).start() - elif command == 'receive': - sender_public_key_path = input("输入发送方的公钥文件路径: ") - threading.Thread(target=self.receive_file, args=(sender_public_key_path,)).start() - elif command == 'exit': - self.running = False - print("正在退出程序。") - break - else: - print("无效的命令。") - -if __name__ == "__main__": - role = input("输入角色 ('sender' 或 'receiver'): ").strip().lower() - app = FileTransferApp(host='0.0.0.0', port=65432, role=role) - app.run() \ No newline at end of file diff --git a/generate_key.py b/generate_key.py new file mode 100644 index 0000000..942db90 --- /dev/null +++ b/generate_key.py @@ -0,0 +1,9 @@ +from utils import generate_rsa_keypair, save_key + +sender_private, sender_public = generate_rsa_keypair() +receiver_private, receiver_public = generate_rsa_keypair() + +save_key('sender_private.pem', sender_private) +save_key('sender_public.pem', sender_public) +save_key('receiver_private.pem', receiver_private) +save_key('receiver_public.pem', receiver_public) diff --git a/receiver.py b/receiver.py index 2865b7c..8f15c7b 100644 --- a/receiver.py +++ b/receiver.py @@ -1,30 +1,55 @@ -from Crypto.Cipher import AES, PKCS1_OAEP -from Crypto.PublicKey import RSA import json import base64 -from encryption_utils import AsymmetricEncryption, SymmetricEncryption - -class Receiver: - def __init__(self, private_key, sender_public_key): - self.private_key = RSA.import_key(private_key) - self.sender_public_key = RSA.import_key(sender_public_key) - self.asym_enc = AsymmetricEncryption() - self.sym_enc = SymmetricEncryption() - - def receive_file(self, data): - data = json.loads(data) - enc_session_key = base64.b64decode(data['enc_session_key']) - nonce = base64.b64decode(data['nonce']) - tag = base64.b64decode(data['tag']) - ciphertext = base64.b64decode(data['ciphertext']) - signature = base64.b64decode(data['signature']) - - cipher_rsa = PKCS1_OAEP.new(self.private_key) - session_key = cipher_rsa.decrypt(enc_session_key) - - file_data = self.sym_enc.decrypt(nonce, ciphertext, tag, session_key) - - if self.asym_enc.verify_signature(file_data, signature, self.sender_public_key): - return file_data - else: - raise ValueError("签名验证失败") \ No newline at end of file +import socket +from utils import aes_decrypt, rsa_decrypt, verify_signature, load_key + +def receive_file(port, receiver_private_key, sender_public_key): + # 启动服务监听 + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(('', port)) + s.listen(1) + print(f"接收方正在监听端口 {port}...") + + conn, addr = s.accept() + print(f"来自 {addr} 的连接已建立!") + + with conn: + # 接收数据 + data = conn.recv(65536) # 最大接收 64KB 数据 + data_packet = json.loads(data.decode('utf-8')) + + # 解码 Base64 数据 + nonce = base64.b64decode(data_packet['nonce']) + ciphertext = base64.b64decode(data_packet['ciphertext']) + tag = base64.b64decode(data_packet['tag']) + encrypted_key = base64.b64decode(data_packet['encrypted_key']) + signature = base64.b64decode(data_packet['signature']) + filename = data_packet['filename'] + + # 使用接收方私钥解密AES密钥 + aes_key = rsa_decrypt(encrypted_key, receiver_private_key) + + # 使用AES密钥解密文件内容 + try: + file_data = aes_decrypt(nonce, ciphertext, tag, aes_key) + + # 验证签名 + if verify_signature(sender_public_key, file_data, signature): + print("签名验证成功,文件未被篡改!") + # 保存解密后的文件 + with open(f"received_{filename}", 'wb') as f: + f.write(file_data) + print(f"文件已保存为 received_{filename}") + else: + print("签名验证失败,文件可能被篡改!") + except Exception as e: + print(f"文件解密或验证过程中出错:{e}") + +if __name__ == "__main__": + # 加载密钥 + receiver_private_key = load_key('receiver_private.pem') + sender_public_key = load_key('sender_public.pem') + + # 监听端口 + port = 12345 + receive_file(port, receiver_private_key, sender_public_key) diff --git a/run_example.py b/run_example.py deleted file mode 100644 index 2c9bfaa..0000000 --- a/run_example.py +++ /dev/null @@ -1,138 +0,0 @@ -import socket -import threading -from Crypto.PublicKey import RSA -from sender import Sender -from receiver import Receiver - -class FileTransferApp: - def __init__(self, host, port, role): - self.host = host - self.port = port - self.role = role - self.private_key = None - self.public_key = None - self.running = True - - def generate_keys(self): - key = RSA.generate(2048) - self.private_key = key.export_key() - self.public_key = key.publickey().export_key() - if self.role == 'sender': - priv_filename = 'send_private.pem' - pub_filename = 'send_public.pem' - else: - priv_filename = 'receive_private.pem' - pub_filename = 'receive_public.pem' - with open(priv_filename, 'wb') as priv_file: - priv_file.write(self.private_key) - with open(pub_filename, 'wb') as pub_file: - pub_file.write(self.public_key) - print(f"密钥生成成功,已保存到 {priv_filename} 和 {pub_filename}。") - - def load_keys(self): - if self.role == 'sender': - priv_filename = 'send_private.pem' - pub_filename = 'send_public.pem' - else: - priv_filename = 'receive_private.pem' - pub_filename = 'receive_public.pem' - try: - with open(priv_filename, 'rb') as priv_file: - self.private_key = priv_file.read() - with open(pub_filename, 'rb') as pub_file: - self.public_key = pub_file.read() - print("密钥加载成功。") - except FileNotFoundError: - print("密钥文件未找到,请先生成密钥。") - - def load_public_key(self, filepath): - try: - with open(filepath, 'rb') as pub_file: - return pub_file.read() - except FileNotFoundError: - print(f"公钥文件 {filepath} 未找到。") - return None - - def send_file(self, filepath, receiver_host, receiver_public_key_path): - receiver_public_key = self.load_public_key(receiver_public_key_path) - if receiver_public_key is None: - return - - try: - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.connect((receiver_host, self.port)) - - sender = Sender(filepath, receiver_public_key, self.private_key) - data_to_send = sender.send_file() - if data_to_send is None: - print("文件加密失败,未发送。") - return - - s.sendall(data_to_send.encode()) - print("文件发送成功。") - except Exception as e: - print(f"发送文件时发生错误: {e}") - - def receive_file(self, sender_public_key_path): - sender_public_key = self.load_public_key(sender_public_key_path) - if sender_public_key is None: - return - - try: - if self.private_key is None: - raise ValueError("未生成私钥,请先生成密钥。") - - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.bind((self.host, self.port)) - s.listen() - print(f"服务器正在 {self.host}:{self.port} 监听...") - conn, addr = s.accept() - with conn: - print(f"已连接到 {addr}") - data = b'' - while True: - packet = conn.recv(1024) - if not packet: - break - data += packet - - receiver = Receiver(self.private_key, sender_public_key) - decrypted_data = receiver.receive_file(data.decode()) - - if decrypted_data is not None: - with open('received_file', 'wb') as f: - f.write(decrypted_data) - print("文件接收并解密成功。") - else: - print("解密失败,文件未保存。") - except ValueError as ve: - print(f"值错误: {ve}") - except Exception as e: - print(f"接收文件时发生错误: {e}") - - def run(self): - while self.running: - command = input("输入 'generate_keys' 生成密钥,'load_keys' 加载密钥,'send' 发送文件,'receive' 接收文件,或 'exit' 退出程序: ").strip().lower() - if command == 'generate_keys': - self.generate_keys() - elif command == 'load_keys': - self.load_keys() - elif command == 'send': - filepath = input("输入要发送的文件路径: ") - receiver_host = input("输入接收方的计算机IP地址: ") - receiver_public_key_path = input("输入接收方的公钥文件路径: ") - threading.Thread(target=self.send_file, args=(filepath, receiver_host, receiver_public_key_path)).start() - elif command == 'receive': - sender_public_key_path = input("输入发送方的公钥文件路径: ") - threading.Thread(target=self.receive_file, args=(sender_public_key_path,)).start() - elif command == 'exit': - self.running = False - print("正在退出程序。") - break - else: - print("无效的命令。") - -if __name__ == "__main__": - role = input("输入角色 ('sender' 或 'receiver'): ").strip().lower() - app = FileTransferApp(host='0.0.0.0', port=65432, role=role) - app.run() \ No newline at end of file diff --git a/sender.py b/sender.py index 4ac039a..37a449d 100644 --- a/sender.py +++ b/sender.py @@ -1,35 +1,53 @@ -from Crypto.Cipher import AES, PKCS1_OAEP -from Crypto.Random import get_random_bytes -from Crypto.PublicKey import RSA +import os import json import base64 -from encryption_utils import AsymmetricEncryption, SymmetricEncryption - -class Sender: - def __init__(self, filepath, receiver_public_key, sender_private_key): - self.filepath = filepath - self.receiver_public_key = RSA.import_key(receiver_public_key) - self.sender_private_key = RSA.import_key(sender_private_key) - self.asym_enc = AsymmetricEncryption() - self.sym_enc = SymmetricEncryption() - - def send_file(self): - with open(self.filepath, 'rb') as f: - file_data = f.read() - - session_key = get_random_bytes(16) - cipher_rsa = PKCS1_OAEP.new(self.receiver_public_key) - enc_session_key = cipher_rsa.encrypt(session_key) - - nonce, ciphertext, tag = self.sym_enc.encrypt(file_data, session_key) - signature = self.asym_enc.sign_data(file_data) - - data_to_send = { - 'enc_session_key': base64.b64encode(enc_session_key).decode(), - 'nonce': base64.b64encode(nonce).decode(), - 'tag': base64.b64encode(tag).decode(), - 'ciphertext': base64.b64encode(ciphertext).decode(), - 'signature': base64.b64encode(signature).decode() - } - - return json.dumps(data_to_send) \ No newline at end of file +import socket +from utils import aes_encrypt, rsa_encrypt, generate_signature, load_key + +def send_file(filename, receiver_ip, receiver_port, receiver_public_key, sender_private_key): + # 读取文件内容 + with open(filename, 'rb') as f: + file_data = f.read() + + # 生成随机AES密钥 + aes_key = os.urandom(16) + + # 加密文件 + nonce, ciphertext, tag = aes_encrypt(file_data, aes_key) + + # 使用接收方公钥加密AES密钥 + encrypted_aes_key = rsa_encrypt(aes_key, receiver_public_key) + + # 生成数字签名(针对原始文件内容) + signature = generate_signature(sender_private_key, file_data) + + # 使用 Base64 对所有数据进行编码 + data_packet = { + 'nonce': base64.b64encode(nonce).decode(), + 'ciphertext': base64.b64encode(ciphertext).decode(), + 'tag': base64.b64encode(tag).decode(), + 'encrypted_key': base64.b64encode(encrypted_aes_key).decode(), + 'signature': base64.b64encode(signature).decode(), + 'filename': os.path.basename(filename) + } + + # 转换为 JSON 格式 + data_packet_json = json.dumps(data_packet) + + # 建立网络连接并发送数据 + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((receiver_ip, receiver_port)) + s.sendall(data_packet_json.encode('utf-8')) + print("文件已发送!") + +if __name__ == "__main__": + # 加载密钥 + receiver_public_key = load_key('receiver_public.pem') + sender_private_key = load_key('sender_private.pem') + + # 文件路径和接收方信息 + filename = '1.txt' + receiver_ip = '192.168.199.134' # 替换为接收方的IP地址 + receiver_port = 12345 + + send_file(filename, receiver_ip, receiver_port, receiver_public_key, sender_private_key) diff --git a/server.py b/server.py new file mode 100644 index 0000000..1213eca --- /dev/null +++ b/server.py @@ -0,0 +1,42 @@ +import os +import json +from utils import aes_encrypt, rsa_encrypt, generate_signature, load_key + +def send_file(filename, receiver_public_key, sender_private_key): + # 读取文件内容 + with open(filename, 'rb') as f: + file_data = f.read() + + # 生成随机AES密钥 + aes_key = os.urandom(16) + + # 加密文件 + nonce, ciphertext, tag = aes_encrypt(file_data, aes_key) + + # 使用接收方公钥加密AES密钥 + encrypted_aes_key = rsa_encrypt(aes_key, receiver_public_key) + + # 生成数字签名(针对原始文件内容) + signature = generate_signature(sender_private_key, file_data) + + # 封装数据包 + data_packet = { + 'nonce': base64.b64encode(nonce).decode(), + 'ciphertext': base64.b64encode(ciphertext).decode(), + 'tag': base64.b64encode(tag).decode(), + 'encrypted_key': base64.b64encode(encrypted_aes_key).decode(), + 'signature': base64.b64encode(signature).decode(), + 'filename': os.path.basename(filename) + } + + # 保存数据包到文件 + with open('data_packet.json', 'w') as f: + json.dump(data_packet, f) + + print("文件已加密并发送。") + +if __name__ == "__main__": + receiver_public_key = load_key('receiver_public.pem') + sender_private_key = load_key('sender_private.pem') + send_file('example.txt', receiver_public_key, sender_private_key) + diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..ed6f17f --- /dev/null +++ b/utils.py @@ -0,0 +1,70 @@ +from Crypto.PublicKey import RSA +from Crypto.Cipher import PKCS1_OAEP, AES +from Crypto.Signature import pkcs1_15 +from Crypto.Hash import SHA256 +import base64 +import os + + +# 生成RSA密钥对 +def generate_rsa_keypair(): + key = RSA.generate(2048) + private_key = key.export_key() + public_key = key.publickey().export_key() + return private_key, public_key + + +# 保存密钥到文件 +def save_key(filename, key): + with open(filename, 'wb') as f: + f.write(key) + + +# 加载密钥 +def load_key(filename): + with open(filename, 'rb') as f: + return f.read() + + +# AES加密文件内容 +def aes_encrypt(data, key): + cipher = AES.new(key, AES.MODE_EAX) + ciphertext, tag = cipher.encrypt_and_digest(data) + return cipher.nonce, ciphertext, tag + + +# AES解密文件内容 +def aes_decrypt(nonce, ciphertext, tag, key): + cipher = AES.new(key, AES.MODE_EAX, nonce=nonce) + return cipher.decrypt_and_verify(ciphertext, tag) + + +# 使用RSA加密对称密钥 +def rsa_encrypt(data, public_key): + cipher = PKCS1_OAEP.new(RSA.import_key(public_key)) + return cipher.encrypt(data) + + +# 使用RSA解密对称密钥 +def rsa_decrypt(data, private_key): + cipher = PKCS1_OAEP.new(RSA.import_key(private_key)) + return cipher.decrypt(data) + + +# 生成数字签名 +def generate_signature(private_key, data): + key = RSA.import_key(private_key) + h = SHA256.new(data) + signature = pkcs1_15.new(key).sign(h) + return signature + + +# 验证数字签名 +def verify_signature(public_key, data, signature): + key = RSA.import_key(public_key) + h = SHA256.new(data) + try: + pkcs1_15.new(key).verify(h, signature) + return True + except (ValueError, TypeError): + return False -- 2.34.1 From b3d733bf43c3ef92c1d85c22b963e7fde302c9f8 Mon Sep 17 00:00:00 2001 From: pwycnofz4 <3493145958@qq.com> Date: Wed, 18 Dec 2024 10:34:02 +0800 Subject: [PATCH 06/11] Initial commit --- LICENSE | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 75 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..27972e4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,73 @@ +Creative Commons Attribution-NoDerivs 1.0 + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DRAFT LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. + +License + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + +1. Definitions + + a. "Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License. + + b. "Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. + + c. "Licensor" means the individual or entity that offers the Work under the terms of this License. + + d. "Original Author" means the individual or entity who created the Work. + + e. "Work" means the copyrightable work of authorship offered under the terms of this License. + + f. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. + +2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: + + a. to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works; + + b. to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works; + +The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by Licensor are hereby reserved. + +4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + + a. You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any reference to such Licensor or the Original Author, as requested. + + b. If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or any Collective Works, You must keep intact all copyright notices for the Work and give the Original Author credit reasonable to the medium or means You are utilizing by conveying the name (or pseudonym if applicable) of the Original Author if supplied; the title of the Work if supplied. Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit. + +5. Representations, Warranties and Disclaimer + + a. By offering the Work for public release under this License, Licensor represents and warrants that, to the best of Licensor's knowledge after reasonable inquiry: + + i. Licensor has secured all rights in the Work necessary to grant the license rights hereunder and to permit the lawful exercise of the rights granted hereunder without You having any obligation to pay any royalties, compulsory license fees, residuals or any other payments; + + ii. The Work does not infringe the copyright, trademark, publicity rights, common law rights or any other right of any third party or constitute defamation, invasion of privacy or other tortious injury to any third party. + + b. EXCEPT AS EXPRESSLY STATED IN THIS LICENSE OR OTHERWISE AGREED IN WRITING OR REQUIRED BY APPLICABLE LAW, THE WORK IS LICENSED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES REGARDING THE CONTENTS OR ACCURACY OF THE WORK. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, AND EXCEPT FOR DAMAGES ARISING FROM LIABILITY TO A THIRD PARTY RESULTING FROM BREACH OF THE WARRANTIES IN SECTION 5, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + + a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. + + b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. + +8. Miscellaneous + + a. Each time You distribute or publicly digitally perform the Work or a Collective Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. + + b. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + + c. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. + + d. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. + +Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor. + +Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, neither party will use the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. + +Creative Commons may be contacted at http://creativecommons.org/. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2879b8 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# file_tran + -- 2.34.1 From dd5aaa7447f5331691d49ccdaf28fa42581791fd Mon Sep 17 00:00:00 2001 From: vernuser Date: Wed, 18 Dec 2024 10:34:58 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E5=B7=B2=E6=88=90=E5=8A=9F=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E8=99=9A=E6=8B=9F=E6=9C=BA=E5=92=8C=E7=89=A9?= =?UTF-8?q?=E7=90=86=E6=9C=BA=E4=B9=8B=E9=97=B4=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.txt | 2 +- sender.py | 2 +- server.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/1.txt b/1.txt index 56a6051..576552d 100644 --- a/1.txt +++ b/1.txt @@ -1 +1 @@ -1 \ No newline at end of file +166666 \ No newline at end of file diff --git a/sender.py b/sender.py index 37a449d..2e707c9 100644 --- a/sender.py +++ b/sender.py @@ -47,7 +47,7 @@ if __name__ == "__main__": # 文件路径和接收方信息 filename = '1.txt' - receiver_ip = '192.168.199.134' # 替换为接收方的IP地址 + receiver_ip = '192.168.98.130' # 替换为接收方的IP地址 receiver_port = 12345 send_file(filename, receiver_ip, receiver_port, receiver_public_key, sender_private_key) diff --git a/server.py b/server.py index 1213eca..c4974b2 100644 --- a/server.py +++ b/server.py @@ -1,7 +1,7 @@ import os import json from utils import aes_encrypt, rsa_encrypt, generate_signature, load_key - +import base64 def send_file(filename, receiver_public_key, sender_private_key): # 读取文件内容 with open(filename, 'rb') as f: @@ -38,5 +38,5 @@ def send_file(filename, receiver_public_key, sender_private_key): if __name__ == "__main__": receiver_public_key = load_key('receiver_public.pem') sender_private_key = load_key('sender_private.pem') - send_file('example.txt', receiver_public_key, sender_private_key) + send_file('1.txt', receiver_public_key, sender_private_key) -- 2.34.1 From 216cbd4dd5a2564694821a95361ed37129a06caa Mon Sep 17 00:00:00 2001 From: vernuser Date: Wed, 18 Dec 2024 10:36:28 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E5=B7=B2=E6=88=90=E5=8A=9F=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E8=99=9A=E6=8B=9F=E6=9C=BA=E5=92=8C=E7=89=A9?= =?UTF-8?q?=E7=90=86=E6=9C=BA=E4=B9=8B=E9=97=B4=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inspectionProfiles/profiles_settings.xml | 6 + .idea/material_theme_project_new.xml | 12 + .idea/misc.xml | 7 + .idea/vcs.xml | 6 + .idea/workspace.xml | 321 ++++++++++++++++++ data_packet.json | 1 + private.pem | 9 + public.pem | 4 + receiver_private.pem | 27 ++ receiver_public.pem | 9 + sender_private.pem | 27 ++ sender_public.pem | 9 + 12 files changed, 438 insertions(+) create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/material_theme_project_new.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 data_packet.json create mode 100644 private.pem create mode 100644 public.pem create mode 100644 receiver_private.pem create mode 100644 receiver_public.pem create mode 100644 sender_private.pem create mode 100644 sender_public.pem diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/material_theme_project_new.xml b/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..c764730 --- /dev/null +++ b/.idea/material_theme_project_new.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f8a22e9 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..9661ac7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..2e347e3 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + { + "history": [ + { + "assignee": "vernuser" + } + ], + "lastFilter": { + "assignee": "vernuser" + } +} + { + "selectedUrlAndAccountId": { + "url": "https://github.com/vernuser/cryptography_homework.git", + "accountId": "8b7e9b97-86ab-4db0-a673-929e037f7c36" + } +} + { + "associatedIndex": 6 +} + + + + + + + { + "keyToString": { + "Python.client.executor": "Run", + "Python.encryption_utils.executor": "Run", + "Python.file_transfer.executor": "Run", + "Python.generate_key.executor": "Run", + "Python.generate_keys.executor": "Run", + "Python.receiver.executor": "Run", + "Python.sender.executor": "Run", + "Python.server.executor": "Run", + "Python.utils.executor": "Run", + "RunOnceActivity.ShowReadmeOnStart": "true", + "RunOnceActivity.git.unshallow": "true", + "git-widget-placeholder": "annn", + "last_opened_file_path": "D:/college/大三/应用密码学课设", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "nodejs_package_manager_path": "npm", + "vue.rearranger.settings.migration": "true" + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1733790319291 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_packet.json b/data_packet.json new file mode 100644 index 0000000..ca12c10 --- /dev/null +++ b/data_packet.json @@ -0,0 +1 @@ +{"nonce": "viRm4Dv0Hc1LnifER06rOw==", "ciphertext": "4Q==", "tag": "HD05+MIgwuWKStAA1DAelA==", "encrypted_key": "YkZ48DIhZzn4mjkzyajDZ8QCDvLFvp3+5N9stM4Bk8elaroz8hPY0UFfewxfYrj0Uz8jimYYANULsXE9itCHKWIaZC+XIIBfd13+eh4rDGuFipXy1ua6EwGDM8arGass4Prwy3G9pxX8j4iPKHWSgfSeqfKpMMBTVqadO5zPFXUOxqFjDOoKAO2lYusOdCIN5/X0sNQd7Bbc9RS59vG8N6yOGagwaATtEciSYr/4SVaqUTlyGiyegOb8OSoplj7jOyOvbUsaHEy3mVE7q992zImyPm+mvQjbWHS0gat+vzTMWRTVmbd8AdnXy3xnCDKhizsowKBtu6x4ksct1u9A5Q==", "signature": "ZUD0Nb2/4AAQRW1KQZIPrlZI7MtPbjM144TP3uIsBwtVTEO2Ew1g5cEb/ZAGSzIlyAiyqN/HVPYOKqpmzdLDHZtn2bQB6AjphLTgl0wwLjOhVc7QLHddWBQoetEhetSXdNZqCaQRb05p0TCA4J01fThVDbmonpEoAaR4xkDPw2zQKIFnYohkQY7xpqOFHfVCa4v/98LgUKkGkMOVXxLqvgVuUwmCWw+Or3WcIA9pxz4438v/VC1fuYGzk3bXHfnSoDstrXCQvfpsQ22O9vY3wwb2gxSxOHZWMMn8b542tzGAw9Ul/x8yCnjcdF1GxbEHoljgR5iSlqsJ85r2WNIo6A==", "filename": "1.txt"} \ No newline at end of file diff --git a/private.pem b/private.pem new file mode 100644 index 0000000..138f6d8 --- /dev/null +++ b/private.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBPQIBAAJBAKJRCS1LQm9GAgZejtry1W0wMANwQQau01PeezV6DY7TOG+G08cv +boN4UaS5comyK7QKIr6WVi/4o+Pm5UcZsQ0CAwEAAQJAY0EgVnUd48Mwe8qYmmRB +hCoiQggDi12eVjvGpbXDPWF3yHX+mVbqrJY3oi9Ub9iJW8Lqw97DcBp/74fvvxd/ +9QIjAPQTvQk8a7yTItR/Tyl/UStL0e+3KY6wuhWeEzACMV7JFcMCHwCqPtsRTG8e +ZBgat2p3ih2tkkO/XNshxOLibUZiIO8CIwCpH2A2HSK96OoSeiB9LZYtvPy78Jug +Hr7iKcU719kjx4wHAh8AqULQ/wPlPmv54yYUfkEdfKJ9JNcnLw3XHZPTdGCVAiJa +N3aZQDyYTX+/8V0E7vxaUlYJMgwXtXs+94qi25rsIWQr +-----END RSA PRIVATE KEY----- diff --git a/public.pem b/public.pem new file mode 100644 index 0000000..9cb3710 --- /dev/null +++ b/public.pem @@ -0,0 +1,4 @@ +-----BEGIN RSA PUBLIC KEY----- +MEgCQQCiUQktS0JvRgIGXo7a8tVtMDADcEEGrtNT3ns1eg2O0zhvhtPHL26DeFGk +uXKJsiu0CiK+llYv+KPj5uVHGbENAgMBAAE= +-----END RSA PUBLIC KEY----- diff --git a/receiver_private.pem b/receiver_private.pem new file mode 100644 index 0000000..8aefb56 --- /dev/null +++ b/receiver_private.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAqcmg7dhBByM+WbVKZ+5wfEO2eCRD0OhyjGZaVMEkfkv9jWon +H8nY9HT8lziJByNbs6ZbZnFkPoUxBi52938Bq2pTAJ3Z5l06qLfd6ryVdAO0IxZG +3+RZ2mfL4Jwg7jTrJ5ygRaiV/K8FjSzAkrEYHGwKc7mfxkyqmWbdq4f4ETBsiZ6d +SCoMqtDiSmeZ6/zjryAOGhqHDX/Zh3BqqOcapT1jm6Kf4Pc/BcpsHYQzblve3Frj +DWnQCzHGBN4AfQ8qmrQAXCaFa8xzAnzgvznVk411Bu2Rmsp1EWrBC5uY8x0IYF7b +MDi2/Bl5XAbPU32fCo141v2r/NeSV20p2k7DxwIDAQABAoIBAEY3qFHlBxOsHCue +gayU3DlQCaULHm7FyyXMaJw3ml+PDsfOuGp5oDuNLC9gBq+IjHKyIIev6my+yaUM +T1AQ2wBowvX00jpmoQ1IqULchhSKOZPvMRWECzL7jUIRX78T7JKfwFq+m3T6bxnR +Ab1I9zc96V6tzGmGqGEzvQYk/88fYglzuU8xz2uXiKj4/T8XnejuQj7hGKzPdKyf +zrDTbZ1vrFQutmgWMUMakAyFvn81KFzezhld53VgLSh+6k7tH8bxgzJ/b6BD74Wg +Na6XkM0xu2OamduNZczpBq2S3QkDPtihSfcZYUQ+z/VGLKsM2LkIGZ7VMgz447y4 +TquhrDUCgYEAvqXVpYm9jPRWPGOMNA00wT3nbA3LjiddVtDFte2JN+JxiYRHvNtj +ALVZKifpKAmZSm6wVXWZ39LrGv4L0lNvKsGb3JM3bExJ4FmZsqpMzWCOkKM+Q9Cc +7tVwr2f13Gm2OYAn3dHpXo2knDtsDi2rwDmyAyOUEgANPFCj2v0NViMCgYEA4/05 +Mawn0QTGsIhKHjtWWh3zOQUhroEPR7jqO19/BAE9srJEPuI6rOC4e6exiv/s81zR +qVsUQMHNfVaV7ka4yCmrUJHPYmvWNA9bZYSXH6AxMmd48SO9gAQx1nMR6YQrxZGW +GkzihxcGi7e8slXeJsCQ2tY0truJy2R4CYglTA0CgYEArhP8Zb/EnW0JRPDctzaL +whtFMYvTHwTgnIHa1ciEL8wLQbbQTijAWIg+V1jD83P4TVeOmSndi9sqI6Zuouje +K9tG9vxRcgiiuED4L4SCxlDxPC5ij0dv1EB+ORujClRYOF7FiCzAez64XJOBkdyv +48CKw4T8EgeMDlPPmgjP4aMCgYAs3atAtDFNt9Pl75wuYNz4dQZlRTZAohNAuQoX +Tw6u2hOrM9usSFblqH+FjhWpVf3qUmzMGClfKQRoUv7EWlSIx3J4M4mNQ81uh0sk +KjiXN64WzjgFtFPZennYSuLOgn0eryzL1i+KCCT4n9rZeX5zP9gByL+s6jEOvqHE +tm8ojQKBgQCxId3KRqYnmgFbefuuuqbonILGPNPZhkgRNT2l3J85v2IoofhZLsGB +AfS4mrkQ7UwzoaWdMOsfUYX/H0IWBs6blE/WL2OLPIfDWnmCTNftvbQouKhdMCwd +rOCwEZ3bH99O8rzvcdEmsgx+AK1g/3PpVFs4P8QGa0qNAIoORWKBbw== +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/receiver_public.pem b/receiver_public.pem new file mode 100644 index 0000000..83df805 --- /dev/null +++ b/receiver_public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqcmg7dhBByM+WbVKZ+5w +fEO2eCRD0OhyjGZaVMEkfkv9jWonH8nY9HT8lziJByNbs6ZbZnFkPoUxBi52938B +q2pTAJ3Z5l06qLfd6ryVdAO0IxZG3+RZ2mfL4Jwg7jTrJ5ygRaiV/K8FjSzAkrEY +HGwKc7mfxkyqmWbdq4f4ETBsiZ6dSCoMqtDiSmeZ6/zjryAOGhqHDX/Zh3BqqOca +pT1jm6Kf4Pc/BcpsHYQzblve3FrjDWnQCzHGBN4AfQ8qmrQAXCaFa8xzAnzgvznV +k411Bu2Rmsp1EWrBC5uY8x0IYF7bMDi2/Bl5XAbPU32fCo141v2r/NeSV20p2k7D +xwIDAQAB +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/sender_private.pem b/sender_private.pem new file mode 100644 index 0000000..ab6233c --- /dev/null +++ b/sender_private.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAtSEr81A8CZPXnscsBgOkbQcrn3/JELmndlf2Ysez8sKCgz04 +pB4XII0o7f2FZkDNLOu5fqs5OmSQd1IZReknGudcw5QJTUEvTKLzbkJNSJzhf0+k +H5yv9M3nS9DB6+VftjP0Hl84148UqpMUq71BygfwCFiUwgvUBbCfpO+gqth+oa38 +wmcHQUeHYFhsJRGn2wI3URNuZIcJjOax2SCVAqRM/vyAS0Q7MSiGNV0BkVudhWkG +0/uaIvCRxO/F3TB9F4x5mHgCt1/cnHeQ4H8a7EsEmypSQ2oGB+oRt4GsvfFHwZGz +8uOUxQkGGCqNt1cLcHoOHuFJBHCSWwN/kF1feQIDAQABAoIBABjj/BQtnHJ8fI73 +M9eHvJq294mtl8XSnW6n29XrN5FOpXy/dv8mm2r/uvYpdqF8mjVoF0+O3AhoNWoQ +QCTZS2RpEthViYmyQXu4kNdACTrHRD2ohhdKAuwTN4u1nlB6btKtBQj/cOI+aUqf +d6G6GkZXHOcotRiNY498nBOgUmXnqw+AMEDabzO2v2je+XBX5QCcHnfoTCsvlmqL +Am2Jr2Oq1pdO2kEDkDTPEJNdqNvVzVhcF5FSIR09jMsMEAUW9zyfcG+WvCWWDwC0 +IcLSXmPYyfa2RNNaUoow3vTqFKBLt2KfE1FArwZkVIsVWwW+ucgEbvtXTbCOUrKl +oFyga9kCgYEAzWpRazlPsHHoYu/n40q8BdS/xWnchIlWgMKJCPXRDcJ4FLs3DpeU +tD/gyQCzZQ25sa8FpGhXvsaXibkY+f8TlFvUTNptP+5HRDfiZhJgCrdAiAQ8bu8U +u82nSf2w6paLmt7cR6yIEk/lLmHBsNICH2HvXk22HGOEFjQIV3Mh2/8CgYEA4bvY +grmCN6bIDq0Ws4KwcUnv7GqTS1BAsPr9YiZVst+wrNyozb9YZY913NwGcVJhebug +nXLP2OCQdc778lKvsGfYUoTfnlW9VSxhtC/YMUnQniVVmOwXuS+lf2rgdlxfX7qs +KHE5G1stbIIcDd6+ggIy7/OOLfCvcr6JXoNtpIcCgYEAgM5FJa43WRXkOX3j83Oe +eS2R3vFltLoFwxG5KiQyJaWm9KD8girstSZFBuVomFpF8bQlHpXLR7ZxuYuWrNSU +63e1pUdmMCtzBsTgM08caDvGvEOjvZAveSAY4V2x/TfPbJqImG0Imir9M9tawEy/ +xfv8RC8Inb6NSfrwrB1mwvMCgYA1GvYyuuXRpeEG4t2mWaac4GIbYm9IlpbBjCq0 +PoSG0m1EHZ1w2gU3z2pRDUpOuqzH8MY2hF41jY8uyAUp2x4OCEAyGaRqIY2rTgem +VmMsJUt5CRt8IH7sSDNNKJ2p+s1NPiNmWEyxDOBA2NM0yCRVfaLyJIBcenUsL3st +ywmuXQKBgDkgYTRIh3DtGZ9+NhjgkFJNwKHt3j5bq+7ySnDERBtJHcsKfQN/1f1f +JVbHAw6D4fJwp+F3ZMAWcgxHuuTSaus1i5Wb1vrvcEUzaYUjOkEDCV2Ow/Qb/Ssc +vSjFMSE4KhB4z3ry3UnK8dOtIVudBKNTAmEREx7H/ClDMm/3GEGn +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/sender_public.pem b/sender_public.pem new file mode 100644 index 0000000..cc78e47 --- /dev/null +++ b/sender_public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtSEr81A8CZPXnscsBgOk +bQcrn3/JELmndlf2Ysez8sKCgz04pB4XII0o7f2FZkDNLOu5fqs5OmSQd1IZRekn +Gudcw5QJTUEvTKLzbkJNSJzhf0+kH5yv9M3nS9DB6+VftjP0Hl84148UqpMUq71B +ygfwCFiUwgvUBbCfpO+gqth+oa38wmcHQUeHYFhsJRGn2wI3URNuZIcJjOax2SCV +AqRM/vyAS0Q7MSiGNV0BkVudhWkG0/uaIvCRxO/F3TB9F4x5mHgCt1/cnHeQ4H8a +7EsEmypSQ2oGB+oRt4GsvfFHwZGz8uOUxQkGGCqNt1cLcHoOHuFJBHCSWwN/kF1f +eQIDAQAB +-----END PUBLIC KEY----- \ No newline at end of file -- 2.34.1 From 533611cf14bd40303bf68ecc3bc15033198f647d Mon Sep 17 00:00:00 2001 From: vernuser Date: Sat, 21 Dec 2024 19:59:20 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E5=8A=A0=E4=BA=86ui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 57 +++++++++++----- private.pem | 9 --- public.pem | 4 -- receiver_private.pem | 50 +++++++------- receiver_public.pem | 14 ++-- sender_private.pem | 50 +++++++------- sender_public.pem | 14 ++-- ui.py | 158 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 262 insertions(+), 94 deletions(-) delete mode 100644 private.pem delete mode 100644 public.pem create mode 100644 ui.py diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 2e347e3..500c1d5 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,7 +4,7 @@