ADD file via upload

main
pyxhe2owb 8 months ago
parent ba88ffe280
commit 51adade261

@ -0,0 +1,192 @@
import sys
import socket
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QLineEdit, QLabel, QComboBox
from PyQt5.QtCore import Qt
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.Random import get_random_bytes
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from Crypto.Util.Padding import pad
import hashlib
import os
class FileTransferApp(QWidget):
def __init__(self):
super().__init__()
# 生成公钥和私钥
self.generate_keys_if_not_exists()
self.init_ui()
def init_ui(self):
self.setWindowTitle('文件加密和传输')
self.setGeometry(100, 100, 400, 300)
layout = QVBoxLayout()
self.file_label = QLabel('未选择文件')
layout.addWidget(self.file_label)
self.select_button = QPushButton('选择文件')
self.select_button.clicked.connect(self.select_file)
layout.addWidget(self.select_button)
self.server_label = QLabel('服务器 IP:')
layout.addWidget(self.server_label)
self.server_ip = QLineEdit(self)
layout.addWidget(self.server_ip)
self.server_port_label = QLabel('服务器端口:')
layout.addWidget(self.server_port_label)
self.server_port = QLineEdit(self)
self.server_port.setText('59290') # 默认端口
layout.addWidget(self.server_port)
self.algorithm_label = QLabel('选择加密算法:')
layout.addWidget(self.algorithm_label)
self.algorithm_combo = QComboBox(self)
self.algorithm_combo.addItem('AES')
layout.addWidget(self.algorithm_combo)
self.mode_label = QLabel('选择加密模式:')
layout.addWidget(self.mode_label)
self.mode_combo = QComboBox(self)
self.mode_combo.addItem('CBC')
self.mode_combo.addItem('ECB')
layout.addWidget(self.mode_combo)
self.send_button = QPushButton('发送加密文件')
self.send_button.clicked.connect(self.send_file)
layout.addWidget(self.send_button)
self.setLayout(layout)
def select_file(self):
options = QFileDialog.Options()
filename, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "所有文件 (*);;文本文件 (*.txt)", options=options)
if filename:
self.file_label.setText(f'选择的文件: {filename}')
self.file_path = filename
def generate_keys_if_not_exists(self):
"""生成公钥和私钥,如果文件不存在"""
if not os.path.exists('public.pem') or not os.path.exists('private.pem'):
print("正在生成公钥和私钥...")
self.generate_keys()
else:
print("公钥和私钥已存在。")
def generate_keys(self):
"""生成公钥和私钥并保存为文件"""
key = RSA.generate(2048)
# 导出私钥
private_key = key.export_key()
with open('private.pem', 'wb') as f:
f.write(private_key)
print("私钥已保存为 'private.pem'")
# 导出公钥
public_key = key.publickey().export_key()
with open('public.pem', 'wb') as f:
f.write(public_key)
print("公钥已保存为 'public.pem'")
def load_public_key(self):
# 从文件加载接收方公钥(用于加密会话密钥)
with open('receiver_public.pem', 'rb') as f:
public_key = RSA.import_key(f.read())
return public_key
def load_private_key(self):
# 从文件加载私钥(用于签名文件)
with open('private.pem', 'rb') as f:
private_key = RSA.import_key(f.read())
return private_key
def encrypt_file(self, filename, public_key):
# 为 AES 加密生成随机会话密钥
session_key = get_random_bytes(16)
# 选择加密模式
mode = self.mode_combo.currentText()
if mode == 'CBC':
cipher_aes = AES.new(session_key, AES.MODE_CBC)
iv = cipher_aes.iv # 获取 CBC 模式使用的 IV
elif mode == 'ECB':
cipher_aes = AES.new(session_key, AES.MODE_ECB)
iv = None
# 加密文件
with open(filename, 'rb') as f:
plaintext = f.read()
ciphertext = cipher_aes.encrypt(pad(plaintext, AES.block_size)) # 对明文进行填充,以满足块大小要求
# 使用 RSA 加密会话密钥
cipher_rsa = PKCS1_OAEP.new(public_key)
encrypted_session_key = cipher_rsa.encrypt(session_key)
return encrypted_session_key, iv, ciphertext
def sign_file(self, filename, private_key):
# 计算文件的 SHA-256 哈希值
hash_obj = SHA256.new()
with open(filename, 'rb') as f:
while chunk := f.read(4096):
hash_obj.update(chunk)
# 使用私钥签名哈希值
signer = pkcs1_15.new(private_key)
signature = signer.sign(hash_obj)
return signature
def send_file(self):
# 获取服务器地址和端口
host = self.server_ip.text()
port = int(self.server_port.text())
# 加载公钥(用于加密会话密钥)
public_key = self.load_public_key()
# 加载私钥(用于签名文件)
private_key = self.load_private_key()
# 加密选择的文件
encrypted_session_key, iv, ciphertext = self.encrypt_file(self.file_path, public_key)
# 签名文件
signature = self.sign_file(self.file_path, private_key)
# 建立 socket 连接
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((host, port))
# 发送加密的会话密钥、IV、密文和签名
client_socket.sendall(encrypted_session_key)
client_socket.sendall(iv)
client_socket.sendall(ciphertext)
client_socket.sendall(signature)
client_socket.close()
print("文件发送成功。")
# 提示用户
self.file_label.setText('文件发送成功!')
def main():
app = QApplication(sys.argv)
ex = FileTransferApp()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Loading…
Cancel
Save