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.
231 lines
10 KiB
231 lines
10 KiB
# -*- coding: utf-8 -*-
|
|
import io
|
|
|
|
# Form implementation generated from reading ui file 'sender_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.
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Form implementation generated from reading ui file 'sender_ui.ui'
|
|
#
|
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
|
import sys
|
|
from PyQt5.QtWidgets import QFileDialog,QMainWindow,QMessageBox
|
|
from gmssl import sm4, func
|
|
import json
|
|
import socket
|
|
from Crypto.Cipher import AES
|
|
from binascii import b2a_hex, a2b_hex
|
|
import random
|
|
import string
|
|
import tkinter as tk
|
|
from tkinter import filedialog
|
|
from Crypto.PublicKey import RSA
|
|
from Crypto.Cipher import PKCS1_OAEP
|
|
from Crypto.Signature import PKCS1_v1_5
|
|
from OpenSSL import crypto
|
|
from OpenSSL.crypto import PKey
|
|
from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM, FILETYPE_ASN1
|
|
from OpenSSL.crypto import dump_privatekey, dump_publickey
|
|
import hashlib
|
|
from Crypto.Hash import SHA512
|
|
import rsa
|
|
import base64
|
|
import pickle
|
|
#导入加密算法的类
|
|
class Ui_MainWindow(object):
|
|
def setupUi(self, MainWindow,sender):
|
|
MainWindow.setObjectName("MainWindow")
|
|
MainWindow.resize(839, 600)
|
|
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
|
self.centralwidget.setObjectName("centralwidget")
|
|
self.enbutton = QtWidgets.QPushButton(self.centralwidget)
|
|
self.enbutton.setGeometry(QtCore.QRect(560, 240, 121, 51))
|
|
self.enbutton.setObjectName("enbutton")
|
|
self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
|
|
self.textBrowser.setGeometry(QtCore.QRect(10, 10, 541, 501))
|
|
self.textBrowser.setObjectName("textBrowser")
|
|
self.choose_button = QtWidgets.QPushButton(self.centralwidget)
|
|
self.choose_button.setGeometry(QtCore.QRect(560, 110, 121, 51))
|
|
self.choose_button.setObjectName("choose_button")
|
|
self.algorithm_box = QtWidgets.QComboBox(self.centralwidget)
|
|
self.algorithm_box.setGeometry(QtCore.QRect(560, 160, 121, 41))
|
|
self.algorithm_box.setObjectName("algorithm_box")
|
|
self.mode_box = QtWidgets.QComboBox(self.centralwidget)
|
|
self.mode_box.setGeometry(QtCore.QRect(560, 200, 121, 41))
|
|
self.mode_box.setObjectName("mode_box")
|
|
self.envelope_button = QtWidgets.QPushButton(self.centralwidget)
|
|
self.envelope_button.setGeometry(QtCore.QRect(560, 290, 121, 51))
|
|
self.envelope_button.setObjectName("envelope_button")
|
|
MainWindow.setCentralWidget(self.centralwidget)
|
|
self.menubar = QtWidgets.QMenuBar(MainWindow)
|
|
self.menubar.setGeometry(QtCore.QRect(0, 0, 839, 23))
|
|
self.menubar.setObjectName("menubar")
|
|
MainWindow.setMenuBar(self.menubar)
|
|
self.statusbar = QtWidgets.QStatusBar(MainWindow)
|
|
self.statusbar.setObjectName("statusbar")
|
|
MainWindow.setStatusBar(self.statusbar)
|
|
self.retranslateUi(MainWindow)
|
|
self.choose_button.clicked.connect(self.choose_file) # type: ignore
|
|
self.enbutton.clicked.connect(self.encrypt) # type: ignore
|
|
self.envelope_button.clicked.connect(self.thread_create) # type: ignore
|
|
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
|
#新增属性
|
|
"""
|
|
self.file_path 文件路径
|
|
self.mode 加密模式
|
|
self.algorithm 选择的加密算法
|
|
self.encrypted_text 加密后的文本
|
|
self.public_key 自己的公钥
|
|
self.private_key 自己的私钥
|
|
self.public_key_other 对方的公钥
|
|
self.key 对称密钥
|
|
self.sender 连接实例
|
|
self.envelope 信封
|
|
"""
|
|
self.file_path= ""
|
|
self.mode=""
|
|
self.algorithm=""
|
|
self.encrypted_text=""
|
|
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.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_other=rsa.PublicKey.load_pkcs1_openssl_pem(f.read())
|
|
print("self.public_key",self.public_key)
|
|
print("self.private_key",self.private_key)
|
|
print("self.public_key_other",self.public_key_other)
|
|
self.key=""
|
|
self.envelope={}
|
|
#等待接收方连接
|
|
self.sender=sender
|
|
def retranslateUi(self, MainWindow):
|
|
_translate = QtCore.QCoreApplication.translate
|
|
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
|
|
self.enbutton.setText(_translate("MainWindow", "加密并封装"))
|
|
self.choose_button.setText(_translate("MainWindow", "选择文件"))
|
|
self.envelope_button.setText(_translate("MainWindow", "发送"))
|
|
self.mode_box.addItems(["ECB", "CBC"])
|
|
self.algorithm_box.addItems(["AES","SM4"])
|
|
def choose_file(self):
|
|
#打开文件选择对话框
|
|
self.file_path, _ = QFileDialog.getOpenFileName(MainWindow, '请选择要进行加密的文件', '', 'All Files (*);;Text Files (*.txt)')
|
|
# 检查文件路径是否为空
|
|
if self.file_path:
|
|
self.textBrowser.append(self.file_path)
|
|
else:
|
|
self.textBrowser.append("no file selected")
|
|
self.textBrowser.append("choose_file")
|
|
|
|
def encrypt(self):
|
|
# 获取用户选择的加密算法
|
|
self.algorithm = self.algorithm_box.currentText()
|
|
self.mode = self.mode_box.currentText()
|
|
with open(self.file_path, 'rb') as f:
|
|
self.plaintext = f.read()
|
|
if self.algorithm=="AES":
|
|
if self.mode=="ECB":
|
|
# #A随机生成16字节的数字和字母组合的字符串
|
|
self.key = ''.join(random.choices(string.ascii_letters + string.digits, k=16)).encode()
|
|
mode = AES.MODE_ECB
|
|
cryptor = AES.new(self.key, mode)
|
|
text = self.plaintext
|
|
length = 16
|
|
count = len(text)
|
|
add = length - (count % length)
|
|
text = text + (b'\0' * add)
|
|
encrypted_text = cryptor.encrypt(text)
|
|
self.encrypted_text = b2a_hex(encrypted_text).decode("utf-8")
|
|
self.textBrowser.append(self.encrypted_text)
|
|
elif self.mode=="CBC":
|
|
#A随机生成16字节的数字和字母组合的字符串
|
|
self.key = ''.join(random.choices(string.ascii_letters + string.digits, k=16)).encode()
|
|
mode = AES.MODE_CBC
|
|
cryptor = AES.new(self.key, mode, self.key)#iv = self.key
|
|
text = self.plaintext
|
|
length = 16
|
|
count = len(text)
|
|
add = length - (count % length)
|
|
text = text + (b'\0' * add)
|
|
encrypted_text = cryptor.encrypt(text)
|
|
self.encrypted_text = b2a_hex(encrypted_text).decode("utf-8")
|
|
self.textBrowser.append(encrypted_text.decode())
|
|
else:
|
|
self.textBrowser.append("mode error")
|
|
elif self.algorithm=="SM4":
|
|
if self.mode=="ECB":
|
|
# 生成sm4的密钥和偏移量
|
|
sm4_key = func.random_hex(16)
|
|
with open(self.file_path, 'rb') as f:
|
|
file_content = f.read()
|
|
print("file_content:",file_content)
|
|
sm4Alg = sm4.CryptSM4()
|
|
sm4Alg.set_key(sm4_key.encode(), sm4.SM4_ENCRYPT)
|
|
encrypted_data = sm4Alg.crypt_ecb(file_content)
|
|
self.encrypted_text = encrypted_data.hex()
|
|
self.textBrowser.append(self.encrypted_text)
|
|
elif self.mode=="CBC":
|
|
# 生成sm4的密钥和偏移量
|
|
sm4_key = func.random_hex(16)
|
|
sm4_iv = func.random_hex(16)
|
|
with open(self.file_path, 'rb') as f:
|
|
file_content = f.read()
|
|
sm4Alg = sm4.CryptSM4()
|
|
sm4Alg.set_key(sm4_key.encode(), sm4.SM4_ENCRYPT)
|
|
encrypted_data = sm4Alg.crypt_cbc(sm4_iv.encode(),file_content)
|
|
self.encrypted_text = encrypted_data.hex()
|
|
self.textBrowser.append(self.encrypted_text)
|
|
else:
|
|
self.textBrowser.append("mode error")
|
|
else:
|
|
self.textBrowser.append("algorithm error")
|
|
#对称密钥加密
|
|
if type(self.key)!=bytes:
|
|
enc_key=rsa.encrypt(self.key.encode(),self.public_key_other)
|
|
else:
|
|
enc_key=rsa.encrypt(self.key,self.public_key_other)
|
|
self.textBrowser.append(base64.b64encode(enc_key).decode())
|
|
#签名
|
|
signature=rsa.sign(self.plaintext,self.private_key,'SHA-256')
|
|
# key = RSA.importKey(self.private_key)
|
|
# sha512_hash = hashlib.sha256(plaintext.encode('utf-8')).hexdigest()
|
|
# h = SHA512.new(sha512_hash.encode("utf-8"))
|
|
# signer = PKCS1_v1_5.new(key)
|
|
# signature = b2a_hex(signer.sign(h)).decode("utf-8")
|
|
# self.textBrowser.append(signature.decode())
|
|
self.envelope={"algorithm":self.algorithm,"mode":self.mode,"ciphertext":self.encrypted_text,"key":enc_key,"signature":signature}
|
|
print(self.envelope)
|
|
self.textBrowser.append("pack successfully")
|
|
def send(self):
|
|
# 发送数据
|
|
self.socketvalue,addr = self.sender.accept()
|
|
while True:
|
|
envelope = json.dumps(self.envelope)
|
|
self.socketvalue.sendall(envelope.encode('utf-8'))
|
|
|
|
def thread_create(self):
|
|
self.send_data = threading.Thread(target=self.send)
|
|
self.send_data.start()
|
|
|
|
if __name__ == "__main__":
|
|
# 发送方建立连接 等待接收方连接
|
|
sender_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
sender_conn.bind(('localhost', 8888))
|
|
sender_conn.listen(5)
|
|
#创建窗口
|
|
app = QtWidgets.QApplication(sys.argv)
|
|
MainWindow = QtWidgets.QMainWindow()
|
|
ui = Ui_MainWindow()
|
|
ui.setupUi(MainWindow,sender_conn)
|
|
MainWindow.show()
|
|
sys.exit(app.exec_()) |