diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..359bb53
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..5ffb332
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+GUI.py
\ No newline at end of file
diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml
new file mode 100644
index 0000000..c7a8a85
--- /dev/null
+++ b/.idea/dbnavigator.xml
@@ -0,0 +1,400 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..a971a2c
--- /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..5a6690a
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/实验.iml b/.idea/实验.iml
new file mode 100644
index 0000000..d0876a7
--- /dev/null
+++ b/.idea/实验.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GUI.py b/GUI.py
new file mode 100644
index 0000000..798613d
--- /dev/null
+++ b/GUI.py
@@ -0,0 +1,47 @@
+import tkinter as tk
+import subprocess
+import threading
+
+# 使用线程来运行 NEW.py和 NEV.py。
+def run_new():
+ try:
+ threading.Thread(target=lambda: subprocess.run(["python", "NEW.py"])).start()
+ except FileNotFoundError:
+ print("找不到NEW.py文件")
+
+
+def run_nev():
+ try:
+ threading.Thread(target=lambda: subprocess.run(["python", "NEV.py"])).start()
+ except FileNotFoundError:
+ print("找不到NEV.py文件")
+
+
+# 创建主窗口
+root = tk.Tk()
+root.title("文件安全传输工具")
+# 设置窗口大小
+root.geometry("300x150")
+
+# 创建标签
+label = tk.Label(root, text="请选择您的身份:")
+label.pack(pady=10)
+
+# 创建按钮框架,用于在同一行放置按钮
+button_frame = tk.Frame(root)
+button_frame.pack()
+
+# 创建发送方按钮
+sender_button = tk.Button(button_frame, text="发送方", command=run_new)
+sender_button.pack(side=tk.LEFT, padx=10)
+
+# 创建接收方按钮
+receiver_button = tk.Button(button_frame, text="接收方", command=run_nev)
+receiver_button.pack(side=tk.LEFT, padx=10)
+
+# 创建关闭按钮
+confirm_button = tk.Button(button_frame, text="关闭", command=root.destroy)
+confirm_button.pack(side=tk.LEFT, padx=10)
+
+# 运行主循环
+root.mainloop()
\ No newline at end of file
diff --git a/NEV.py b/NEV.py
new file mode 100644
index 0000000..a3876c4
--- /dev/null
+++ b/NEV.py
@@ -0,0 +1,195 @@
+import os
+import pickle
+import socket
+import tkinter as tk
+from tkinter import filedialog, ttk, messagebox
+from cryptography.hazmat.primitives.asymmetric import padding
+from cryptography.hazmat.primitives import hashes, serialization
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
+import hashlib
+
+
+# 去除填充函数
+def unpad(data):
+ padding_length = data[-1]
+ if padding_length > len(data):
+ return data
+ return data[:-padding_length]
+
+
+# 解密文件函数
+def decrypt_file(encrypted_data, key, iv, algorithm, mode):
+ mode_mapping = {
+ "CBC": modes.CBC,
+ "CFB": modes.CFB
+ }
+ if algorithm == "AES":
+ # 对于AES算法,IV长度为16字节,无需处理
+ cipher = Cipher(algorithms.AES(key), mode_mapping[mode](iv))
+ elif algorithm == "DES":
+ # 确保IV长度为8字节
+ iv = iv[:8]
+ cipher = Cipher(algorithms.TripleDES(key), mode_mapping[mode](iv))
+ else:
+ raise ValueError("不支持该算法")
+
+ decryptor = cipher.decryptor()
+ decrypted_data = decryptor.update(encrypted_data) + decryptor.finalize()
+ return decrypted_data
+
+
+# 计算哈希值函数
+def calculate_hash(data):
+ digest = hashes.Hash(hashes.SHA256())
+ digest.update(data)
+ return digest.finalize()
+
+
+# 验证签名函数
+def verify_signature(public_key, signature, hash_value):
+ try:
+ public_key.verify(
+ signature,
+ hash_value,
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA256()),
+ salt_length=padding.PSS.MAX_LENGTH
+ ),
+ hashes.SHA256()
+ )
+ return True
+ except Exception:
+ return False
+
+
+# 解密对称密钥函数
+def decrypt_symmetric_key(private_key, encrypted_key):
+ decrypted_key = private_key.decrypt(
+ encrypted_key,
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=None
+ )
+ )
+ return decrypted_key
+
+
+# 计算文件的 MD5 校验和
+def calculate_md5(data):
+ md5 = hashlib.md5()
+ md5.update(data)
+ return md5.hexdigest()
+
+
+# 接收文件函数
+def receive_file(server_ip, server_port, output_dir, algorithm, mode):
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+ s.bind((server_ip, server_port))
+ s.listen(1)
+ print(f"等待连接,监听端口 {server_port}...")
+ conn, addr = s.accept()
+ with conn:
+ print(f"接收到连接来自: {addr}")
+ data = b""
+ while True:
+ packet = conn.recv(4096)
+ if not packet:
+ break
+ data += packet
+
+ package = pickle.loads(data)
+
+ encrypted_file = package['encrypted_file']
+ iv = package['iv']
+ encrypted_symmetric_key = package['encrypted_symmetric_key']
+ signature = package['signature']
+ received_algorithm = package['algorithm']
+ received_mode = package['mode']
+ received_md5_checksum = package['md5_checksum']
+ file_extension = package['file_extension']
+ # 从封装包中提取发送方公钥
+ sender_public_pem = package['sender_public_key']
+ sender_public_key = serialization.load_pem_public_key(sender_public_pem)
+
+ if algorithm!= received_algorithm or mode!= received_mode:
+ raise ValueError("选择的解密算法或模式与发送方不一致")
+
+ with open("receiver_private_key.pem", "rb") as f:
+ receiver_private_key = serialization.load_pem_private_key(
+ f.read(),
+ password=None
+ )
+
+ symmetric_key = decrypt_symmetric_key(receiver_private_key, encrypted_symmetric_key)
+
+ decrypted_file = decrypt_file(encrypted_file, symmetric_key, iv, algorithm, mode)
+ decrypted_file = unpad(decrypted_file)
+
+ file_hash = calculate_hash(encrypted_file)
+
+ is_valid = verify_signature(sender_public_key, signature, file_hash)
+ return is_valid, output_dir, file_extension, decrypted_file
+
+
+# 主函数,用于启动 GUI 界面
+def receiver_main():
+ def select_output_dir():
+ output_dir.set(filedialog.askdirectory())
+
+ def start_receiving():
+ if not output_dir.get():
+ print("请选择保存文件的路径!")
+ return
+ algorithm = algorithm_var.get()
+ mode = mode_var.get()
+ try:
+ is_valid, output_dir_path, file_extension, decrypted_file = receive_file(
+ server_ip.get(), int(server_port.get()), output_dir.get(), algorithm, mode
+ )
+ result_label.config(text=f"接收方验证签名结果: {is_valid}")
+ if is_valid:
+ output_file_path = os.path.join(output_dir_path, f"decrypted_file.{file_extension}")
+ with open(output_file_path, "wb") as f:
+ f.write(decrypted_file)
+ messagebox.showinfo("提示", "接收成功")
+ except Exception as e:
+ print(f"接收过程中发生错误: {e}")
+
+ root = tk.Tk()
+ root.title("接收方")
+ root.geometry("450x300") # 适当增加窗口高度以显示新标签
+
+ server_ip = tk.StringVar(value="127.0.0.1")
+ server_port = tk.StringVar(value="12345")
+ output_dir = tk.StringVar()
+ algorithm_var = tk.StringVar(value="AES")
+ mode_var = tk.StringVar(value="CBC")
+
+ ttk.Label(root, text="监听 IP:").grid(row=0, column=0, sticky=tk.W, pady=5)
+ ttk.Entry(root, textvariable=server_ip).grid(row=0, column=1, pady=5)
+
+ ttk.Label(root, text="监听端口:").grid(row=1, column=0, sticky=tk.W, pady=5)
+ ttk.Entry(root, textvariable=server_port).grid(row=1, column=1, pady=5)
+
+ ttk.Label(root, text="选择保存文件的路径:").grid(row=2, column=0, sticky=tk.W, pady=5)
+ ttk.Entry(root, textvariable=output_dir, width=30).grid(row=2, column=1, pady=5)
+ ttk.Button(root, text="选择目录", command=select_output_dir).grid(row=2, column=2, pady=5)
+
+ ttk.Label(root, text="选择解密算法:").grid(row=3, column=0, sticky=tk.W, pady=5)
+ ttk.Combobox(root, textvariable=algorithm_var, values=["AES", "DES"], state="readonly").grid(row=3, column=1, pady=5)
+
+ ttk.Label(root, text="选择解密模式:").grid(row=4, column=0, sticky=tk.W, pady=5)
+ ttk.Combobox(root, textvariable=mode_var, values=["CBC", "CFB"], state="readonly").grid(row=4, column=1, pady=5)
+
+ ttk.Button(root, text="开始接收文件", command=start_receiving).grid(row=5, columnspan=3, pady=20)
+
+ # 新增显示验证结果的标签
+ result_label = ttk.Label(root, text="")
+ result_label.grid(row=6, columnspan=3, pady=10)
+
+ root.mainloop()
+
+
+if __name__ == "__main__":
+ receiver_main()
\ No newline at end of file
diff --git a/NEW.py b/NEW.py
new file mode 100644
index 0000000..e5e5a4b
--- /dev/null
+++ b/NEW.py
@@ -0,0 +1,269 @@
+import os
+import pickle
+import socket
+import tkinter as tk
+from tkinter import filedialog, ttk, messagebox
+from cryptography.hazmat.primitives.asymmetric import rsa, padding
+from cryptography.hazmat.primitives import hashes, serialization
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
+import hashlib
+
+
+# 生成并保存发送方密钥对
+def generate_and_save_sender_keys():
+ private_key = rsa.generate_private_key(
+ public_exponent=65537,
+ key_size=2048,
+ )
+ public_key = private_key.public_key()
+
+ with open('sender_private_key.pem', 'wb') as f:
+ f.write(private_key.private_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PrivateFormat.PKCS8,
+ encryption_algorithm=serialization.NoEncryption()
+ ))
+
+ with open('sender_public_key.pem', 'wb') as f:
+ f.write(public_key.public_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PublicFormat.SubjectPublicKeyInfo
+ ))
+
+ return private_key, public_key
+
+
+# 加载发送方密钥对
+def load_sender_keys():
+ try:
+ with open('sender_private_key.pem', 'rb') as f:
+ private_key = serialization.load_pem_private_key(
+ f.read(),
+ password=None
+ )
+ with open('sender_public_key.pem', 'rb') as f:
+ public_key = serialization.load_pem_public_key(f.read())
+ return private_key, public_key
+ except FileNotFoundError:
+ return generate_and_save_sender_keys()
+
+
+sender_private_key, sender_public_key = load_sender_keys()
+
+# 用于存储接收方公钥的变量
+receiver_public_key = None
+
+
+# 填充数据函数
+def pad(data, block_size):
+ padding_length = block_size - (len(data) % block_size)
+ if padding_length == 0:
+ padding_length = block_size
+ padding = bytes([padding_length]) * padding_length
+ return data + padding
+
+
+# 加密文件函数
+def encrypt_file(file_path, key, algorithm, mode):
+ with open(file_path, 'rb') as f:
+ file_data = f.read()
+ if algorithm == "AES":
+ block_size = 16
+ elif algorithm == "DES":
+ block_size = 8
+ else:
+ raise ValueError("Unsupported algorithm")
+ file_data = pad(file_data, block_size)
+
+ mode_mapping = {
+ "CBC": modes.CBC,
+ "CFB": modes.CFB
+ }
+ if algorithm == "AES":
+ iv = os.urandom(16)
+ elif algorithm == "DES":
+ iv = os.urandom(8) # 生成8字节的IV用于DES算法
+ else:
+ raise ValueError("Unsupported algorithm")
+
+ if algorithm == "AES":
+ cipher = Cipher(algorithms.AES(key), mode_mapping[mode](iv))
+ elif algorithm == "DES":
+ cipher = Cipher(algorithms.TripleDES(key), mode_mapping[mode](iv))
+ else:
+ raise ValueError("Unsupported algorithm")
+
+ encryptor = cipher.encryptor()
+ encrypted_data = encryptor.update(file_data) + encryptor.finalize()
+ return encrypted_data, iv
+
+
+# 计算哈希值函数
+def calculate_hash(data):
+ digest = hashes.Hash(hashes.SHA256())
+ digest.update(data)
+ return digest.finalize()
+
+
+# 对哈希值进行签名函数
+def sign_hash(private_key, hash_value):
+ signature = private_key.sign(
+ hash_value,
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA256()),
+ salt_length=padding.PSS.MAX_LENGTH
+ ),
+ hashes.SHA256()
+ )
+ return signature
+
+
+# 加密对称密钥函数
+def encrypt_symmetric_key(public_key, symmetric_key):
+ encrypted_key = public_key.encrypt(
+ symmetric_key,
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=None
+ )
+ )
+ return encrypted_key
+
+
+# 计算文件的 MD5 校验和
+def calculate_md5(data):
+ md5 = hashlib.md5()
+ md5.update(data)
+ return md5.hexdigest()
+
+
+# 发送文件函数
+def send_file(server_ip, server_port, package):
+ try:
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
+ s.connect((server_ip, server_port))
+ s.sendall(pickle.dumps(package))
+ return True
+ except Exception as e:
+ print(f"连接失败: {e}")
+ return False
+
+
+# 导入接收方公钥的函数
+def import_receiver_public_key():
+ global receiver_public_key
+ file_path = filedialog.askopenfilename(filetypes=[("PEM files", "*.pem")])
+ if file_path:
+ try:
+ with open(file_path, 'rb') as f:
+ receiver_public_key = serialization.load_pem_public_key(f.read())
+ messagebox.showinfo("提示", "接收方公钥导入成功")
+ except Exception as e:
+ messagebox.showerror("错误", f"导入接收方公钥失败: {e}")
+
+
+# 主函数,用于启动 GUI 界面
+def sender_main():
+ def select_file():
+ file_path.set(filedialog.askopenfilename())
+
+ def send():
+ global receiver_public_key
+ file = file_path.get()
+ algorithm = algorithm_var.get()
+ mode = mode_var.get()
+
+ if not file:
+ messagebox.showerror("错误", "请选择文件")
+ return
+
+ if algorithm == "AES":
+ key_size = 32
+ elif algorithm == "DES":
+ key_size = 24
+ else:
+ print("不支持的算法!")
+ return
+
+ if mode == "CBC":
+ pass
+ elif mode == "CFB":
+ pass
+ else:
+ print("不支持的模式!")
+ return
+
+ if not receiver_public_key:
+ messagebox.showerror("错误", "请导入证书")
+ return
+
+ symmetric_key = os.urandom(key_size)
+ encrypted_file, iv = encrypt_file(file, symmetric_key, algorithm, mode)
+
+ file_hash = calculate_hash(encrypted_file)
+ signature = sign_hash(sender_private_key, file_hash)
+
+ sender_public_pem = sender_public_key.public_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PublicFormat.SubjectPublicKeyInfo
+ )
+
+ encrypted_symmetric_key = encrypt_symmetric_key(receiver_public_key, symmetric_key)
+
+ md5_checksum = calculate_md5(encrypted_file)
+
+ file_extension = os.path.splitext(file)[1][1:]
+ # 在封装包中添加发送方公钥
+ package = {
+ 'encrypted_file': encrypted_file,
+ 'iv': iv,
+ 'encrypted_symmetric_key': encrypted_symmetric_key,
+ 'signature': signature,
+ 'algorithm': algorithm,
+ 'mode': mode,
+ 'md5_checksum': md5_checksum,
+ 'file_extension': file_extension,
+ 'sender_public_key': sender_public_pem
+ }
+
+ if send_file(server_ip.get(), int(server_port.get()), package):
+ messagebox.showinfo("提示", "发送成功")
+ else:
+ messagebox.showerror("错误", "连接失败")
+
+
+ root = tk.Tk()
+ root.title("发送方")
+ root.geometry("490x250")
+
+ file_path = tk.StringVar()
+ algorithm_var = tk.StringVar(value="AES")
+ mode_var = tk.StringVar(value="CBC")
+ server_ip = tk.StringVar(value="127.0.0.1")
+ server_port = tk.StringVar(value="12345")
+
+ ttk.Label(root, text="选择文件:").grid(row=0, column=0, sticky=tk.W, pady=5)
+ ttk.Entry(root, textvariable=file_path, width=30).grid(row=0, column=1, pady=5)
+ ttk.Button(root, text="浏览", command=select_file).grid(row=0, column=2, pady=5)
+ ttk.Button(root, text="导入证书", command=import_receiver_public_key).grid(row=0, column=3, pady=5)
+
+ ttk.Label(root, text="选择加密算法:").grid(row=1, column=0, sticky=tk.W, pady=5)
+ ttk.Combobox(root, textvariable=algorithm_var, values=["AES", "DES"], state="readonly").grid(row=1, column=1, pady=5)
+
+ ttk.Label(root, text="选择加密模式:").grid(row=2, column=0, sticky=tk.W, pady=5)
+ ttk.Combobox(root, textvariable=mode_var, values=["CBC", "CFB"], state="readonly").grid(row=2, column=1, pady=5)
+
+ ttk.Label(root, text="接收方 IP:").grid(row=3, column=0, sticky=tk.W, pady=5)
+ ttk.Entry(root, textvariable=server_ip).grid(row=3, column=1, pady=5)
+
+ ttk.Label(root, text="接收方端口:").grid(row=4, column=0, sticky=tk.W, pady=5)
+ ttk.Entry(root, textvariable=server_port).grid(row=4, column=1, pady=5)
+
+ ttk.Button(root, text="发送文件", command=send).grid(row=5, columnspan=3, pady=20)
+
+ root.mainloop()
+
+
+if __name__ == "__main__":
+ sender_main()
\ No newline at end of file
diff --git a/__pycache__/NEV.cpython-311.pyc b/__pycache__/NEV.cpython-311.pyc
new file mode 100644
index 0000000..43c5a10
Binary files /dev/null and b/__pycache__/NEV.cpython-311.pyc differ
diff --git a/__pycache__/NEW.cpython-311.pyc b/__pycache__/NEW.cpython-311.pyc
new file mode 100644
index 0000000..5d57d0d
Binary files /dev/null and b/__pycache__/NEW.cpython-311.pyc differ
diff --git a/__pycache__/receiver.cpython-311.pyc b/__pycache__/receiver.cpython-311.pyc
new file mode 100644
index 0000000..230bbba
Binary files /dev/null and b/__pycache__/receiver.cpython-311.pyc differ
diff --git a/__pycache__/sender.cpython-311.pyc b/__pycache__/sender.cpython-311.pyc
new file mode 100644
index 0000000..0d36cb6
Binary files /dev/null and b/__pycache__/sender.cpython-311.pyc differ
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..c76673d
--- /dev/null
+++ b/main.py
@@ -0,0 +1,77 @@
+import socket
+import json
+from cryptography.fernet import Fernet
+from cryptography.hazmat.primitives.asymmetric import rsa, padding
+from cryptography.hazmat.primitives import serialization, hashes
+
+
+def generate_key():
+ return Fernet.generate_key()
+
+
+def encrypt_file(file_path, key):
+ with open(file_path, 'rb') as file:
+ data = file.read()
+ fernet = Fernet(key)
+ encrypted_data = fernet.encrypt(data)
+ return encrypted_data
+
+
+def encrypt_key(public_key, symmetric_key):
+ encrypted_key = public_key.encrypt(
+ symmetric_key,
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA256()),
+ algorithm=hashes.SHA256(),
+ label=None
+ )
+ )
+ return encrypted_key
+
+
+def main():
+ host = '127.0.0.1'
+ port = 49670
+
+ # 创建rsa密钥对
+ private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
+ public_key = private_key.public_key()
+
+ server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ server_socket.bind((host, port))
+ server_socket.listen(1)
+ print("Server is listening...")
+
+ conn, addr = server_socket.accept()
+ print(f"Connection from {addr}")
+
+ # 发送公钥
+ pem = public_key.public_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PublicFormat.SubjectPublicKeyInfo
+ )
+ conn.sendall(pem)
+
+ # 加密文件,这里假设要发送的文件名为 'example.txt',可根据实际情况修改
+ file_path = 'example.txt'
+ symmetric_key = generate_key()
+ encrypted_data = encrypt_file(file_path, symmetric_key)
+
+ # 用公钥加密对称密钥
+ encrypted_key = encrypt_key(public_key, symmetric_key)
+
+ # 构建数字信封,确保数据编码使用更通用的utf-8格式
+ envelope = {
+ 'algorithm': 'AES',
+ 'key': encrypted_key.hex(),
+ 'file_data': encrypted_data.decode('utf-8')
+ }
+
+ # 发送数字信封,先转换为JSON字符串再编码为字节类型发送
+ conn.sendall(json.dumps(envelope).encode('utf-8'))
+ conn.close()
+ print("File sent successfully.")
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/receiver_private_key.pem b/receiver_private_key.pem
new file mode 100644
index 0000000..1915ff6
--- /dev/null
+++ b/receiver_private_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCFkCLhWcpNPbTu
+12H30PAvVJY7ui5BauTEzfILeH0ki9x3HeUvGmFxeY6JVCO+obio8NT1DWaVl2NC
+6SRhnLRGg2Oq4LgbAOBqBpatF7GL3e1aHzugWmCQdH3oFgw2bQQOrK7OoZc0FXSq
+DvfvMkxn4cgVv75Rcz/GaUzGnmNCzjBH+sQrnQj9my694YUT+HSnabXHDje+EZ2I
+j7wbjQl941RV0mITt4bgJdVE09UuVEIz76K/yRMzrvwsSUwokvt9XFsQvRGyGUC9
+42BPlvxVGz744P6DuXIZ3Dt+DGNhNJliIuLNhIolGO85eqtbPHKeMDPvx1pO+Y4B
+us9AplA/AgMBAAECggEAJoUUWjPAMZirVvrNKWCb9LqLfXxLnNhMVColNYOxa9ne
+Yog/sd8E3Wo2XoriqDcR/789W9Nak6gOm5yLvo8oOvHny791uWv+TPXLfO5JaVI/
+Au/hDXUjRmYibc32BbhZJDZPUA6wgffyJp2cieLSwF8Qip07MVhwuzNhTiMd84UD
+H8vdDCPi6wZ41glMzGCJVRJAAmxz8XkYeMz6ghtMtilAxz30IBnKAFsSgFQGtZJk
+Hg2STxvMWMkn3j6Vnl88YfMAhe+fAbqhDuh/Uy0Py+XaTULUNOJXZtKyCwO3leJm
+PdfeCoQVG4/BYZhd7cZgT9pv0d0FTl9vWg/FC88h4QKBgQC8iiF5B/8/CRiVbq17
+c31ka7pb2oBSJlDpemN7vhA6D9ZwFDDvsFi/ezHLUuizZvuo9pYsFkNKWtgZKE4w
+/nCZqP4HTC9rRIIFf7/XlJuMrRXuAkkbyRWSP9DxfudO+QBVqdXp2pJoPJfiFrkb
+mM3t3GjL7eTCdo9ixItOOsx8jwKBgQC1WkIPegQdbfhCe9taH/DxaWcJkgSpVdwC
+Yhm7dEj+DngRcmTDehXJmaA6mqVMGK2Q4HeYNzUmQPzpAp7NyW4m7E87hj9uzA2m
+2DXzfZuf3GM6vE+DKif3umBV0yEW7oJb6BxE1RDGUC/vfwXinxBDTtiEYOZ26fi5
+1vqcugApUQKBgQClOoCfKuz79yK+QqJyYAHx8Z7+RHzUgZPDKWjp1uUtnReWXXuN
+cwQzuukmgOBB6Ox/ZKqytEgAb6CWW4Y61aEkaL9G8fNUlFNGMnCToz62iDGBxir/
+2Le41YhtO4PG59ztNcusB8rq4r9Qeg17K+y8mb6ViURDT9fU/N4AjvMJ7QKBgGey
+foee+29gjE5nyBuWnA1Oec5tIiE5qR3rvk8DxSEQYPOI97kWvBKUt5wLBW2nxsdK
+stfk6Y1AJ92M1AVTopq7EOs2blsKbtvyUZczQaN9P3g8aTLVDhmHBsLMgOU96Ghp
+JpDtTDQ5cc9+UH0u+vuhwAih5+YjD0gkdxTa/nChAoGBAJJ7Ps+GGlnbAouFMT1S
+bwRuNAVZcNzu5ud0jKAPEvNwa9WFlFObh77taI9aIqGzcibena+7+6ld7sBzo769
+umYbe+3o4nqDIzhL0rZuSG8cq6ajkq1al9WVG/nlJ99YBjaEltmBVVOQ3ysBuGZj
+HR7g/XAyJzUFadT8BEdh/vZm
+-----END PRIVATE KEY-----
diff --git a/receiver_public_key.pem b/receiver_public_key.pem
new file mode 100644
index 0000000..9313d20
--- /dev/null
+++ b/receiver_public_key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhZAi4VnKTT207tdh99Dw
+L1SWO7ouQWrkxM3yC3h9JIvcdx3lLxphcXmOiVQjvqG4qPDU9Q1mlZdjQukkYZy0
+RoNjquC4GwDgagaWrRexi93tWh87oFpgkHR96BYMNm0EDqyuzqGXNBV0qg737zJM
+Z+HIFb++UXM/xmlMxp5jQs4wR/rEK50I/ZsuveGFE/h0p2m1xw43vhGdiI+8G40J
+feNUVdJiE7eG4CXVRNPVLlRCM++iv8kTM678LElMKJL7fVxbEL0RshlAveNgT5b8
+VRs++OD+g7lyGdw7fgxjYTSZYiLizYSKJRjvOXqrWzxynjAz78daTvmOAbrPQKZQ
+PwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/sender_private_key.pem b/sender_private_key.pem
new file mode 100644
index 0000000..6aa741a
--- /dev/null
+++ b/sender_private_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC37VWLRKKVTRnY
+OMJuebhBoaX30zUhv9KiVpCJ1RY+OT3s+4vU2OjaJt6ql6E1xPPbecKGPc+9aZFj
+18jZsZgXC4aVpANP17ApzniAXXjoyYsrAL0e1dxGviZolDfrDJTllP2FIyfmFgRn
+GUVrfcUqSL5DJ/GU9qR1EhSHBVUwmet6HFAXwRDJYZ49YvRHeExnzv7p4qgQkEy1
+G9/phYRS26tvI+910eRRbWcKuGounr1ZOB81Aym8RnRlipUipqpTiCUWvvY2TpEe
+jSPA5WCjzjom8Jo8zepqvImB7G2zIy9/0C+daLtJZUvoCy8CHFmqk2buQXWUIu4C
+6mrsY76fAgMBAAECggEAAI1BEIvTxitiKJ2qQKu2lNBm7bG4iBctVQSb4qyGNkyl
+5DG1QkFJXjgNbaR3ZlllKF6fcwsU/op3/L1Ao+kaZEM16JQKNZBbYVD34teQ5Yog
+FvRmhbY5wA+8qSuk2rLpLLgh89krsAUVywHL7/tYUJDvy3M9MlB3eAqojH4D0G3Z
+llKhYThTmtjIWvvSAXCLL0QSXP/DOGgU4OPLsJ0vxrvXObkzT7WHeHLbfB3y9kTj
+An3zEaTmQulEbpq4QOKjIETtyLcWTbUxaL5baikGWRAkS+BrncSfNqpgsnvgyg1f
+nuTdi2TC+VZIDal+HtYGQgwtIrHzu53NgXUZE3D21QKBgQDhFmtpQoK8LfOkLPW6
+6el9VjvRqvyrLo+ymHqxpYUxPXKFwToqa3TeKY/56kx5cy9oogCV8LwR0Yt7awiz
+Syxv8RBZoPsaVuEaY3FunVcPC+eCE1O2N0pOqIy1Ff/6G94y37U7sSm5oCHJTRET
+ApHJt8m1LmFRRS5QYnzn3Js1/QKBgQDRL82O6u4Ei+11ZjyzQgA75iukZVWKNHrI
+haDTbwdasaItlLKO+xJQEN0IzkPNbuEyrqRMWtqyWaT2fpCkJXZWom8IzLmhL3SD
+Htdiq2VvCt/Pq6SELNzLJT7pbVzuA7HosOK+z+Zc5+TOEPORgKydlNVY452iJP/Y
+lGLHAEtbywKBgGpMUjGFjYQdF2DDMtEwwmnEnb9oxqZ4+LfZNqhKiNo2MK1mEXgT
+A0Af1LSrp637bbo2N5yX8dlgYkTIyXUS3UuIRrZtReiseuYhbGJWv9SFRLGzOudk
+uRzokHq8hwSwwIC6ETa9df0J2KreUF/v6LWgrAt6ec8Nos+nk2FUV6BpAoGBAILY
+VMp9do4PfGN/pJ43vW+6JDg7TksZUmfU9ejqvP3kuF2schfvQeAk/C0C3/RC08fg
+51H/TmZank20kwKpkCDWj39AlygUR9uwUecc8GCJu77pTQmECkNjM7vMtWEHnKPA
+6MOTxTL9teeTQNcVVmNm8iAcl8ARRpsRDcwOChULAoGBALiGuaQvG0uUPjt3Za+n
+I0xV5B5dymFtxjgfHZwldnrW+9rF5omGswLDhn7Iya9+UIoX1rGdG+qqWMtIJcmz
+g2cz2hRdX67tdxnanlMb6ALrQdAXEhLLnXMJAsRxeqsEpUYf+OypYm6XkJkDmgCz
+PfyGudk3oG0VCrXP21/P9H/A
+-----END PRIVATE KEY-----
diff --git a/sender_public_key.pem b/sender_public_key.pem
new file mode 100644
index 0000000..94e8793
--- /dev/null
+++ b/sender_public_key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt+1Vi0SilU0Z2DjCbnm4
+QaGl99M1Ib/SolaQidUWPjk97PuL1Njo2ibeqpehNcTz23nChj3PvWmRY9fI2bGY
+FwuGlaQDT9ewKc54gF146MmLKwC9HtXcRr4maJQ36wyU5ZT9hSMn5hYEZxlFa33F
+Kki+QyfxlPakdRIUhwVVMJnrehxQF8EQyWGePWL0R3hMZ87+6eKoEJBMtRvf6YWE
+UturbyPvddHkUW1nCrhqLp69WTgfNQMpvEZ0ZYqVIqaqU4glFr72Nk6RHo0jwOVg
+o846JvCaPM3qaryJgextsyMvf9AvnWi7SWVL6AsvAhxZqpNm7kF1lCLuAupq7GO+
+nwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/yicixing.py b/yicixing.py
new file mode 100644
index 0000000..09dc7ba
--- /dev/null
+++ b/yicixing.py
@@ -0,0 +1,25 @@
+from cryptography.hazmat.primitives.asymmetric import rsa
+from cryptography.hazmat.primitives import serialization
+def generate_receiver_keys():
+ private_key = rsa.generate_private_key(
+ public_exponent=65537,
+ key_size=2048,
+ )
+ public_key = private_key.public_key()
+
+ # 保存私钥到文件
+ with open('receiver_private_key.pem', 'wb') as f:
+ f.write(private_key.private_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PrivateFormat.PKCS8,
+ encryption_algorithm=serialization.NoEncryption()
+ ))
+
+ # 保存公钥到文件
+ with open('receiver_public_key.pem', 'wb') as f:
+ f.write(public_key.public_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PublicFormat.SubjectPublicKeyInfo
+ ))
+
+generate_receiver_keys()
\ No newline at end of file