You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
9.0 KiB
208 lines
9.0 KiB
# -*- coding: utf-8 -*-
|
|
|
|
# Form implementation generated from reading ui file 'receiver_ui.ui'
|
|
#
|
|
# Created by: PyQt5 UI code generator 5.15.9
|
|
#
|
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
|
# run again. Do not edit this file unless you know what you are doing.
|
|
|
|
import base64
|
|
|
|
from PyQt5.QtWidgets import QFileDialog, QMainWindow
|
|
import socket
|
|
from Crypto.Cipher import AES
|
|
from binascii import b2a_hex, a2b_hex
|
|
from Crypto.PublicKey import RSA
|
|
from Crypto.Cipher import PKCS1_OAEP
|
|
from Crypto.Signature import PKCS1_v1_5
|
|
import hashlib
|
|
from Crypto.Hash import SHA512
|
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
|
import sys
|
|
import json
|
|
from gmssl import sm4, func, sm2, sm3
|
|
from PyQt5.QtWidgets import QMessageBox, QFileDialog,QMainWindow
|
|
import rsa
|
|
# import sm2random
|
|
from OpenSSL import crypto
|
|
import pickle
|
|
import threading
|
|
|
|
class Ui_MainWindow(object):
|
|
def setupUi(self, MainWindow):
|
|
MainWindow.setObjectName("MainWindow")
|
|
MainWindow.resize(800, 602)
|
|
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
|
self.centralwidget.setObjectName("centralwidget")
|
|
self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
|
|
self.textBrowser.setGeometry(QtCore.QRect(10, 10, 541, 501))
|
|
self.textBrowser.setObjectName("textBrowser")
|
|
self.connect_button = QtWidgets.QPushButton(self.centralwidget)
|
|
self.connect_button.setGeometry(QtCore.QRect(560, 60, 121, 51))
|
|
self.connect_button.setObjectName("connect_button")
|
|
self.receive_button = QtWidgets.QPushButton(self.centralwidget)
|
|
self.receive_button.setGeometry(QtCore.QRect(560, 110, 121, 51))
|
|
self.receive_button.setObjectName("receive_button")
|
|
self.decrypt_button = QtWidgets.QPushButton(self.centralwidget)
|
|
self.decrypt_button.setGeometry(QtCore.QRect(560, 160, 121, 51))
|
|
self.decrypt_button.setObjectName("decrypt_button")
|
|
self.verify_button = QtWidgets.QPushButton(self.centralwidget)
|
|
self.verify_button.setGeometry(QtCore.QRect(560, 210, 121, 51))
|
|
self.verify_button.setObjectName("verify_button")
|
|
MainWindow.setCentralWidget(self.centralwidget)
|
|
self.menubar = QtWidgets.QMenuBar(MainWindow)
|
|
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
|
|
self.menubar.setObjectName("menubar")
|
|
MainWindow.setMenuBar(self.menubar)
|
|
self.statusbar = QtWidgets.QStatusBar(MainWindow)
|
|
self.statusbar.setObjectName("statusbar")
|
|
MainWindow.setStatusBar(self.statusbar)
|
|
# 新增属性
|
|
"""
|
|
self.file_path 明文的保存路径
|
|
self.mode 加密模式
|
|
self.algorithm 加密算法
|
|
self.enc_key 加密后的对称密钥
|
|
self.private_key 私钥
|
|
self.public_key 公钥
|
|
self.public_key_other 对方的公钥
|
|
self.iv 初始向量iv
|
|
self.signature 签名
|
|
self.encrypted_text 密文
|
|
self.key 对称密钥
|
|
"""
|
|
self.file_path = ""
|
|
self.mode = ""
|
|
self.algorithm = ""
|
|
self.enc_key = ""
|
|
self.signature=""
|
|
# 打开文件选择对话框
|
|
QMessageBox.information(MainWindow, "提示", "请选择你的私钥文件")
|
|
path = QFileDialog.getOpenFileName()[0]
|
|
# 弹出消息框
|
|
with open(path, "rb") as f:
|
|
self.private_key = rsa.PrivateKey.load_pkcs1(f.read(), 'DER')
|
|
QMessageBox.information(MainWindow, "提示", "请选择你的公钥文件")
|
|
path = QFileDialog.getOpenFileName()[0]
|
|
with open(path, "rb") as f:
|
|
self.public_key = rsa.PublicKey.load_pkcs1_openssl_pem(f.read())
|
|
QMessageBox.information(MainWindow, "提示", "请选择对方的公钥文件")
|
|
path = QFileDialog.getOpenFileName()[0]
|
|
with open(path, "rb") as f:
|
|
self.public_key_other = rsa.PublicKey.load_pkcs1_openssl_pem(f.read())
|
|
self.iv = ""
|
|
self.encrypted_text = ""
|
|
self.key = ""
|
|
self.plaintext = ''
|
|
self.retranslateUi(MainWindow)
|
|
self.receive_button.clicked.connect(self.receive) # type: ignore #原文为self.receive
|
|
self.decrypt_button.clicked.connect(self.decrypt) # type: ignore
|
|
self.verify_button.clicked.connect(self.verify) # type: ignore
|
|
self.connect_button.clicked.connect(self.connect) # type: ignore
|
|
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
|
|
|
|
|
def retranslateUi(self, MainWindow):
|
|
_translate = QtCore.QCoreApplication.translate
|
|
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
|
|
self.connect_button.setText(_translate("MainWindow", "连接发送端"))
|
|
self.receive_button.setText(_translate("MainWindow", "接收文件"))
|
|
self.decrypt_button.setText(_translate("MainWindow", "解密"))
|
|
self.verify_button.setText(_translate("MainWindow", "验证签名"))
|
|
|
|
|
|
# 连接发送端 准备接收数据
|
|
def connect(self):
|
|
self.receiver_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
self.receiver_conn.connect(('localhost', 8888))
|
|
QMessageBox.information(QMainWindow(), '提示', "已连接到服务端")
|
|
# self.client = self.receiver_conn # 继承连接实例
|
|
|
|
# 创建接收消息的线程
|
|
# def thread_create(self):
|
|
# receive_thread = threading.Thread(target=self.receive)
|
|
# receive_thread.daemon = True
|
|
# receive_thread.start()
|
|
|
|
# 接收信封并解封保存,加密后的对称密钥,密文,签名
|
|
def receive(self):
|
|
data = b""
|
|
# while True:
|
|
envelope_dict = self.receiver_conn.recv(88888)
|
|
# if not envelope_dict:
|
|
# break
|
|
data += envelope_dict
|
|
# #将字节流转换为字典
|
|
envelope_dict = pickle.loads(data)
|
|
print(envelope_dict)
|
|
self.signature = envelope_dict['signature']
|
|
self.encrypted_text = envelope_dict['ciphertext']
|
|
self.enc_key = envelope_dict['key']
|
|
self.mode = envelope_dict['mode']
|
|
self.algorithm = envelope_dict['algorithm']
|
|
if self.mode == "CBC":
|
|
self.iv = envelope_dict['iv']
|
|
self.receiver_conn.close()
|
|
def decrypt_key(self):
|
|
# 使用rsa私钥解密对称密钥self.enc_key,赋给self.key
|
|
if type(self.enc_key) != bytes:
|
|
self.enc_key = bytes(self.enc_key, 'utf-8')
|
|
self.key = rsa.decrypt(self.enc_key, self.private_key)
|
|
print("key:",self.key)
|
|
def decrypt(self):
|
|
# 根据模式和加密算法解密
|
|
self.decrypt_key()
|
|
if self.algorithm == "AES":
|
|
if self.mode == "CBC":
|
|
self.mode = AES.MODE_CBC
|
|
cryptor = AES.new(self.key, self.mode, self.key)
|
|
self.plain_text = cryptor.decrypt(a2b_hex(self.encrypted_text))
|
|
print(self.plain_text)
|
|
plaintext = b2a_hex(self.plain_text.rstrip(b'\0')).decode("utf-8")
|
|
self.textBrowser.append(bytes.fromhex(plaintext).decode("utf-8"))
|
|
elif self.mode == "ECB":
|
|
self.mode = AES.MODE_ECB
|
|
cryptor = AES.new(self.key, self.mode)
|
|
self.plain_text = cryptor.decrypt(a2b_hex(self.encrypted_text))
|
|
plaintext = b2a_hex(self.plain_text.rstrip(b'\0')).decode("utf-8")
|
|
self.textBrowser.append(bytes.fromhex(plaintext).decode("utf-8"))
|
|
else:
|
|
print("mode error")
|
|
elif self.algorithm == "SM4":
|
|
if self.mode == "CBC":
|
|
sm4_crypt = sm4.CryptSM4()
|
|
sm4_crypt.set_key(self.key, sm4.SM4_DECRYPT)
|
|
self.plaintext = sm4_crypt.crypt_cbc(self.iv.encode(), bytes.fromhex(self.encrypted_text))
|
|
#打开文件保存对话框
|
|
QMessageBox.information(QMainWindow(), '提示',"选择文件保存路径")
|
|
save_path, _ = QFileDialog.getSaveFileName()
|
|
with open(save_path, "wb") as f:
|
|
f.write(self.plaintext)
|
|
self.textBrowser.append(self.plaintext.decode())
|
|
elif self.mode == "ECB":
|
|
sm4_crypt = sm4.CryptSM4()
|
|
print(self.key)
|
|
sm4_crypt.set_key(self.key, sm4.SM4_DECRYPT)
|
|
self.plaintext = sm4_crypt.crypt_ecb(bytes.fromhex(self.encrypted_text))
|
|
QMessageBox.information(QMainWindow(), '提示',"选择文件保存路径")
|
|
save_path, _ = QFileDialog.getSaveFileName()
|
|
with open(save_path, "wb") as f:
|
|
f.write(self.plaintext)
|
|
self.textBrowser.append(self.plaintext.decode())
|
|
else:
|
|
print("mode,error")
|
|
else:
|
|
print("algorithm,error")
|
|
def verify(self):
|
|
if rsa.verify(self.plaintext,self.signature, self.public_key_other):
|
|
self.textBrowser.append("验证成功")
|
|
else:
|
|
self.textBrowser.append("验证失败")
|
|
if __name__ == "__main__":
|
|
app = QtWidgets.QApplication(sys.argv)
|
|
window = QtWidgets.QMainWindow()
|
|
ui = Ui_MainWindow()
|
|
ui.setupUi(window)
|
|
window.show()
|
|
sys.exit(app.exec_()) |