|
发表于 2024-2-15 21:02:48
|
显示全部楼层
本帖最后由 学习编程中的Ben 于 2024-2-15 21:04 编辑
- from tkinter.filedialog import *
- from ttkbootstrap import *
- from ttkbootstrap.dialogs import *
- import tkinter.messagebox as mb
- import os
- import sys
- import pyperclip
- import logging
- from Crypto import Random
- from Crypto.PublicKey import RSA
- from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
- import base64
- from Crypto.Cipher import AES
- import random
- class main:
- def __init__(self):
- self.root = Window()
- self.root.geometry("600x400")
- self.root.title("加密器 -- 未命名")
- # 创建主菜单栏
- self.menubar = Menu(self.root)
- # 创建子菜单
- self.menuFile = Menu(self.menubar)
- self.menuTools = Menu(self.menubar)
- self.menuHelp = Menu(self.menubar)
- # 将子菜单加入到主菜单栏
- self.menubar.add_cascade(label="文件", menu=self.menuFile)
- self.menubar.add_cascade(label="功能", menu=self.menuTools)
- self.menubar.add_cascade(label="其他", menu=self.menuHelp)
- self.filename = ""
- # 文本框旁边的行号
- self.login = 0
- self.line_number = tk.Text(self.root, width=4, height=15, padx=5, pady=5)
- self.line_number.pack(side=tk.LEFT, fill=tk.Y)
- self.logger = logging.getLogger(__name__)
- # 将主菜单栏加到根窗口
- self.root["menu"] = self.menubar
- # 文本框
- self.w1 = Text(self.root, width=80, height=30, font=('consolas', 10))
- self.w1.pack()
- # 绑定快捷键
- self.root.bind('<Alt-KeyPress-s>', self.saveFile)
- self.root.bind('<Control-KeyPress-s>', self.save_same_File)
- self.root.bind('<Control-KeyPress-o>', self.openFile)
- self.root.bind('<Control-KeyPress-d>', self.all_die)
- self.root.protocol("WM_DELETE_WINDOW", self.ask_to_exit)
- # 显示菜单栏的功能
- self.filemenu()
- self.toolsmenu()
- self.helpsmenu()
- self.key = 0
- # 在调用mainloop后调用sw
- self.root.after(0, self.update_line_numbers)
- # 总行数
- self.line_count = 0
- # 初始内容,用来比较文本框中的内容是否改变
- self.old_text = self.w1.get(1.0, END)
- # 保存状态:1是未保存,0是已保存
- self.is_save = 1
- # 让tkinter跑起来
- self.root.mainloop()
- # 当有内容改变,没保存却要退出时的提醒框
- def ask_to_exit(self):
- if self.old_text != self.w1.get(1.0, END):
- result = mb.askyesnocancel("提示", "是否保存更改?")
- if result is True:
- self.openFile()
- self.root.destroy()
- elif result is False:
- self.root.destroy()
- else:
- self.root.destroy()
- # 判断行数是否改变,若改变就重新加载行数
- def update_line_numbers(self):
- # 原来的行数
- old_hang_num = 0
- # 现在的行数
- hang_num = self.w1.get("1.0", END).count("\n")
- # 判断行数是否改变,若改变则刷新
- if hang_num != old_hang_num:
- # 将旧行数更新
- old_hang_num = self.w1.get("1.0", END).count("\n")
- self.line_count = old_hang_num
- self.line_number.config(state=tk.NORMAL)
- self.line_number.delete("1.0", tk.END)
- for i in range(1, self.line_count + 1):
- self.line_number.insert(tk.END, " " + str(i) + "\n")
- self.line_number.config(state=tk.DISABLED)
- self.root.after(10, self.update_line_numbers)
- # 切换主题的页面
- def themes(self):
- pop = Toplevel()
- pop.title("主题切换")
- pop.geometry("600x200+200+200")
- style = Style()
- theme_names = ["litera", "morph", "darkly", "superhero", "solar", "vapor"]
- theme_selection = Frame(pop)
- # theme_selection.pack(fill=X, expand=YES)
- theme_selection.place(x=10, y=10)
- lbl = Label(theme_selection, text="选择主题:")
- theme_cbo = Combobox(master=theme_selection, text=style.theme.name, values=theme_names, state="readonly")
- theme_cbo.pack(padx=10, side=RIGHT)
- # theme_cbo.place(x=170, y=20)
- theme_cbo.current(theme_names.index(style.theme.name))
- lbl.pack(side=RIGHT)
- # lbl.place(x=70, y=20)
- def change_theme(event):
- theme_cbo_value = theme_cbo.get()
- style.theme_use(theme_cbo_value)
- theme_selected.configure(text=theme_cbo_value)
- theme_cbo.selection_clear()
- theme_cbo.bind('<<ComboboxSelected>>', change_theme)
- theme_selected = Label(
- master=theme_selection,
- text="litera",
- font="-size 24 -weight bold"
- )
- theme_selected.pack(side=LEFT)
- def JieShu():
- pop.destroy()
- # 取消最小化,即为显示窗口
- self.root.state(NORMAL)
- button = Button(pop, text=" 完成<-戳我 ", command=JieShu, bootstyle=(SUCCESS, OUTLINE))
- button.place(x=465, y=155)
- pop.protocol("WM_DELETE_WINDOW", JieShu)
- self.root.iconify()
- def aes_encipher(self):
- k = mb.askokcancel("提示", "本程序的AES不可加密中文\n建议用于加密RSA秘钥\n若强行使用,将会报错!!!\n是否进行加密?")
- if k == False:
- return 0
- pop = Toplevel()
- pop.title("AES加密")
- pop.geometry("650x450+200+200")
- def create_key():
- key = ""
- s = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
- "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
- for i in range(16):
- key += s[random.randint(0, 35)]
- return key
- aes_key = create_key()
- k = str(self.w1.get(1.0, END))
- # AES加密
- encrypted_text = self.aesEncrypt(aes_key, k)
- Label(pop, text="密钥:", font=("microsoft yahei", 20)).place(x=50, y=50)
- txt_key = Text(pop, height=3, width=35)
- txt_key.place(x=180, y=40)
- txt_key.insert('1.0', aes_key)
- txt_key.config(state=DISABLED)
- def save_key():
- try:
- files = [('文本文档', '*.txt')]
- dir_name = 'mi_yao'
- if not os.path.exists(dir_name):
- os.mkdir(dir_name)
- file = asksaveasfile(title='保存文件', defaultextension=files, filetypes=files,
- initialdir='.\\mi_yao\\')
- with open(file.name, 'wb') as f:
- f.write(aes_key.encode("utf-8"))
- print(file.name)
- except AttributeError:
- pass
- button_key = Button(pop, text="保存至文件", command=save_key)
- button_key.place(x=300, y=130)
- Label(pop, text="密文:", font=("microsoft yahei", 20)).place(x=50, y=230)
- txt_encrypted = Text(pop, height=3, width=35)
- txt_encrypted.place(x=180, y=220)
- txt_encrypted.insert('1.0', encrypted_text)
- txt_encrypted.config(state=DISABLED)
- def save_encrypted():
- try:
- files = [('加密文件', '*.wpk')]
- dir_name = 'mi_wen'
- if not os.path.exists(dir_name):
- os.mkdir(dir_name)
- file = asksaveasfile(title='保存文件', defaultextension=files, filetypes=files,
- initialdir='.\\mi_wen\\')
- file.write(encrypted_text)
- print(file.name)
- except AttributeError:
- pass
- def finish():
- pop.destroy()
- self.root.state(NORMAL)
- button_finish = Button(pop, text=" 完成<-戳我 ", command=finish)
- button_finish.place(x=510, y=400)
- pop.protocol("WM_DELETE_WINDOW", finish)
- self.root.iconify()
- button_save_encrypted = Button(pop, text="保存至文件", command=save_encrypted)
- button_save_encrypted.place(x=300, y=310)
- def aesEncrypt(self, key, data):
- BLOCK_SIZE = 16 # Bytes
- pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
- key = key.encode("utf8")
- data = pad(data)
- cipher = AES.new(key, AES.MODE_ECB)
- result = cipher.encrypt(data.encode())
- encodestrs = base64.b64encode(result)
- enctext = encodestrs.decode("utf8")
- return enctext
- def aes_decipher(self):
- pop = Toplevel()
- pop.title("AES解密")
- pop.geometry("450x210+200+200")
- lab_key = Label(pop, text="密钥:", font=("microsoft yahei", 20))
- lab_key.place(x=90, y=20)
- button_upload_key = Button(pop, text="上传密钥文件", command=self.open_file_key)
- button_upload_key.place(x=230, y=33)
- frame = Frame(pop, width=390, height=1)
- frame.place(x=30, y=140)
- button_decrypt = Button(pop, text=" 解密 ", command=lambda: self.decrypt(self.key))
- button_decrypt.place(x=180, y=90)
- button_finish = Button(pop, text=" 完成<-戳我 ", command=lambda: self.finish(pop))
- button_finish.place(x=310, y=160)
- pop.protocol("WM_DELETE_WINDOW", self.finish)
- self.root.iconify()
- def finish(self, win):
- self.root.state(NORMAL)
- win.destroy()
- def open_file_data(self):
- try:
- file_path = askopenfilename(title='选择密文', filetypes=[('加密文件', '*.wpk')], initialdir='.\\mi_wen\\')
- if file_path:
- with open(file_path, 'rb') as f:
- content = f.read()
- print(f.name)
- return content
- except FileNotFoundError:
- mb.showerror('错误', '你没有选择任何文件!')
- def open_file_key(self):
- try:
- file_path = askopenfilename(title='选择密钥文件', filetypes=[('TXT', '*.txt')], initialdir='.\\mi_yao\\')
- if file_path:
- with open(file_path, 'r') as f:
- key = f.read()
- print(f.name)
- self.key = key
- mmb.showinfo("上传成功", "上传成功")
- except FileNotFoundError:
- mb.showerror("错误", "你没有选择任何文件!")
- def decrypt(self, key):
- encrypted_data = self.w1.get(1.0, END)
- decrypted_text = self.aesDecrypt(key, encrypted_data)
- self.w1.delete("1.0", "end")
- self.w1.insert(INSERT, decrypted_text)
- mb.showinfo(title="解密成功", message="解密成功!!!")
- def aesDecrypt(self, key, data):
- BLOCK_SIZE = 16 # Bytes
- unpad = lambda s: s[: -ord(s[len(s) - 1:])]
- key = key.encode("utf8")
- data = base64.b64decode(data)
- cipher = AES.new(key, AES.MODE_ECB)
- text_decrypted = unpad(cipher.decrypt(data))
- text_decrypted = text_decrypted.decode("utf8")
- return text_decrypted
- # RSA加密页面
- def rsa_encipher(self):
- pop = Toplevel()
- pop.title("rsa加密")
- pop.geometry("650x450+200+200")
- k = self.w1.get(1.0, END)
- print(k)
- print(type(k))
- # RSA加密
- test = self.RsaCode()
- res_en = test.long_encrypt(k)
- private_key = test.rsa_private_key # 密钥
- Label(pop, text="密钥:", font=("microsoft yahei", 20)).place(x=50, y=50)
- txt = Text(pop, height=3, width=35)
- txt.place(x=180, y=40)
- txt.insert('1.0', private_key)
- txt.config(state=DISABLED)
- def the_save():
- try:
- files = [('文本文档', '*.txt')]
- dir_name = 'mi_yao'
- if not os.path.exists(dir_name): # os模块判断并创建
- os.mkdir(dir_name)
- file = asksaveasfile(title='保存文件', defaultextension=files, filetypes=files,
- initialdir='.\\mi_yao\\')
- with open(file.name, 'wb') as f:
- f.write(private_key.encode("utf-8"))
- print(file.name)
- except AttributeError:
- pass
- button = Button(pop, text="保存至文件", command=the_save, bootstyle=(PRIMARY, OUTLINE))
- button.place(x=300, y=130)
- Label(pop, text="密文:", font=("microsoft yahei", 20)).place(x=50, y=230)
- txt = Text(pop, height=3, width=35)
- txt.place(x=180, y=220)
- txt.insert('1.0', str(res_en))
- txt.config(state=DISABLED)
- def the_save1():
- try:
- files = [('加密文件', '*.wpk')]
- dir_name = 'mi_wen'
- if not os.path.exists(dir_name): # os模块判断并创建
- os.mkdir(dir_name)
- file = asksaveasfile(title='保存文件', defaultextension=files, filetypes=files,
- initialdir='.\\mi_wen\\')
- file.write(str(res_en))
- print(file.name)
- except AttributeError:
- pass
- def JieShu():
- pop.destroy()
- # 取消最小化,即为显示窗口
- self.root.state(NORMAL)
- button = Button(pop, text=" 完成<-戳我 ", command=JieShu, bootstyle=(SUCCESS, OUTLINE))
- button.place(x=510, y=400)
- pop.protocol("WM_DELETE_WINDOW", JieShu)
- self.root.iconify()
- button = Button(pop, text="保存至文件", command=the_save1, bootstyle=(WARNING, OUTLINE))
- button.place(x=300, y=310)
- # RSA加密函数
- class RsaCode:
- def __init__(self):
- random_generator = Random.new().read
- rsa = RSA.generate(1024, random_generator)
- self.rsa_private_key = str(rsa.exportKey())[2:-1].replace("\\n", "\n")
- self.rsa_public_key = str(rsa.public_key().exportKey())[2:-1].replace("\\n", "\n")
- # print(self.rsa_private_key)
- # print(type(self.rsa_private_key))
- # print(self.rsa_public_key)
- # print(type(self.rsa_public_key))
- def encrypt(self, msg):
- msg = msg.encode('utf-8')
- rsakey = RSA.importKey(self.rsa_public_key)
- cipher = PKCS1_cipher.new(rsakey)
- cipher_text = base64.b64encode(cipher.encrypt(msg))
- return cipher_text
- def decrypt(self, cipher_text):
- rsakey = RSA.importKey(self.rsa_private_key)
- cipher = PKCS1_cipher.new(rsakey)
- random_generator = Random.new().read
- text = cipher.decrypt(base64.b64decode(cipher_text), random_generator)
- return text.decode('utf8')
- def long_encrypt(self, msg):
- msg = msg.encode('utf-8')
- length = len(msg)
- default_length = 117
- # 公钥加密
- pubobj = PKCS1_cipher.new(RSA.importKey(self.rsa_public_key))
- # 长度不用分段
- if length < default_length:
- return base64.b64encode(pubobj.encrypt(msg))
- # 需要分段
- offset = 0
- res = []
- while length - offset > 0:
- if length - offset > default_length:
- res.append(pubobj.encrypt(msg[offset:offset + default_length]))
- else:
- res.append(pubobj.encrypt(msg[offset:]))
- offset += default_length
- byte_data = b''.join(res)
- return base64.b64encode(byte_data)
- def long_decrypt(self, msg):
- print(msg)
- print(type(msg))
- msg = base64.b64decode(msg)
- print(msg)
- length = len(msg)
- default_length = 128
- # 私钥解密
- priobj = PKCS1_cipher.new(RSA.importKey(self.rsa_private_key))
- # 长度不用分段
- if length < default_length:
- return b''.join(priobj.decrypt(msg, b'xyz'))
- # 需要分段
- offset = 0
- res = []
- while length - offset > 0:
- if length - offset > default_length:
- res.append(priobj.decrypt(msg[offset:offset + default_length], b'xyz'))
- else:
- res.append(priobj.decrypt(msg[offset:], b'xyz'))
- offset += default_length
- return b''.join(res).decode('utf8')
- # RSA解密函数
- class Rsa_class_know:
- def __init__(self, w1, root, RsaCode):
- self.pop = Toplevel()
- self.pop.title("rsa解密")
- self.pop.geometry("450x210+200+200")
- self.RsaCode = RsaCode
- self.w1 = w1
- self.root = root
- self.mi_wen = ""
- self.mi_yao = ""
- lab = Label(self.pop, text="密钥:", font=("microsoft yahei", 20))
- # lab.config(fg="red")
- lab.place(x=90, y=20)
- button = Button(self.pop, text="上传密钥文件", command=self.OF_mi_yao, bootstyle=(DANGER, OUTLINE))
- # button.config(background="red")
- button.place(x=230, y=33)
- frame = Frame(self.pop, width=390, height=1)
- frame.place(x=30, y=140)
- button = Button(self.pop, text=" 解密 ", command=self.know, bootstyle=(INFO, OUTLINE))
- button.place(x=180, y=90)
- button = Button(self.pop, text=" 完成<-戳我 ", command=self.JieShu, bootstyle=(SUCCESS, OUTLINE))
- button.place(x=310, y=160)
- self.pop.protocol("WM_DELETE_WINDOW", self.JieShu)
- root.iconify()
- def OF_mi_wen(self):
- c = askopenfilename(title='选择密文', filetypes=[('加密文件', '*.wpk')], initialdir='.\\mi_wen\\')
- try:
- # 以GBK编码打开
- try:
- with open(c) as f:
- content = f.read()
- print(f.name)
- print(content)
- self.mi_wen = content
- except FileNotFoundError:
- mb.showerror('错误', '你没有选择任何文件!')
- except UnicodeDecodeError:
- # 以UTF-8编码打开
- with open(c) as f:
- content = f.read()
- print(f.name)
- print(content)
- self.mi_wen = content
- def OF_mi_yao(self):
- try:
- c = askopenfilename(title='选择秘钥文件', filetypes=[('TXT', '*.txt')], initialdir='.\\mi_yao\\')
- if c:
- self.mi_yao = c
- mb.showinfo("上传成功", "上传成功")
- except FileNotFoundError:
- mb.showerror("错误", "你没有选择任何文件!")
- def know(self):
- test = self.RsaCode()
- with open(self.mi_yao, "r") as f:
- self.mi_yao = f.read()
- test.rsa_private_key = self.mi_yao.replace("\\n", "\n")
- print("**************" + test.rsa_private_key)
- self.mi_wen = self.w1.get(1.0, END)
- res_de = test.long_decrypt(self.mi_wen[2:-1].encode("utf-8"))
- print('res_de', res_de)
- self.w1.delete("1.0", "end")
- self.w1.insert(INSERT, res_de)
- mb.showinfo(title="解密成功", message="解密成功!!!")
- # self.JieShu()
- def JieShu(self):
- self.root.state(NORMAL)
- self.pop.destroy()
- # 取消最小化,即为显示窗口
- # RSA解密调用
- def rsa_know(self):
- self.root.iconify()
- b = self.Rsa_class_know(self.w1, self.root, self.RsaCode)
- # 打开文件
- def openFile(self, pointless=None):
- global filename
- c = askopenfilename(title='打开一个文件',
- filetypes=[('全部文件(图片等无法打开)', '*.*'), ('TXT', '*.txt'), ('Word', '*.word'),
- ('加密文件', '*.wpk'), ('Python文件', '*.py'), ('C++文件', '*.cpp'),
- ('Java文件', '*.java'), ('C文件', '*.c')], initialdir='.\\')
- # print(c.name)
- try:
- # 以GBK编码打开
- try:
- with open(c) as f:
- content = f.read()
- self.w1.delete("1.0", "end")
- self.w1.insert(INSERT, content)
- self.filename = f.name
- self.root.title("加密器 -- " + self.filename)
- print(f.name)
- except FileNotFoundError:
- mb.showerror('错误', '你没有选择任何文件!')
- except UnicodeDecodeError:
- # 以UTF-8编码打开
- with open(c, encoding='utf-8') as f:
- content = f.read()
- self.w1.delete("1.0", "end")
- self.w1.insert(INSERT, content)
- self.filename = f.name
- self.root.title("加密器 -- " + self.filename)
- print(f.name)
- self.old_text = self.w1.get("1.0", END)
- # 另存为文件
- def saveFile(self, pointless=None):
- try:
- files = [('TXT', '*.txt'), ('Word', '*.word'),
- ('Python文件', '*.py'), ('C++文件', '*.cpp'),
- ('Java文件', '*.java'), ('C文件', '*.c')]
- dir_name = 'wenben'
- if not os.path.exists(dir_name): # os模块判断并创建
- os.mkdir(dir_name)
- file = asksaveasfile(title='保存文件', defaultextension=files, filetypes=files, initialdir='.\\wenben\\')
- file.write(self.w1.get(1.0, END))
- file.close()
- file.write(self.w1.get(1.0, END))
- self.filename = file.name
- print(file.name)
- except AttributeError:
- pass
- # 保存文件
- def save_same_File(self, pointless=None):
- try:
- with open(self.filename, "w") as file:
- file.write(self.w1.get(1.0, END))
- mb.showinfo('成功', '保存完毕!')
- except FileNotFoundError:
- mb.showerror("错误", "请打开文件或选择另存为!")
- self.old_text = self.w1.get(1.0, END)
- # 关于
- def about(self):
- mb.showinfo(title="关于", message="由学习编程中的Ben制作\nQQ:1778454661")
- # "文件"子菜单
- def filemenu(self):
- # 添加菜单项
- # self.menuFile.add_command(label="新建 Ctrl+N", command=self.new)
- self.menuFile.add_command(label="打开 Ctrl+O", command=self.openFile)
- # root.bind("<Control-n>", openFile)
- self.menuFile.add_command(label="保存 Ctrl+S", command=self.save_same_File)
- self.menuFile.add_command(label="另存为 Alt+S", command=self.saveFile)
- self.menuFile.add_separator() # 添加分割线
- #self.menuFile.add_command(label="关闭窗口 Alt+D", command=self.destroy)
- self.menuFile.add_command(label="退出 Alt+Q", command=self.all_die)
- # "功能"子菜单
- def toolsmenu(self):
- self.menuTools.add_command(label="RSA加密", command=self.rsa_encipher)
- self.menuTools.add_command(label="RSA解密", command=self.rsa_know)
- self.menuTools.add_command(label="AES加密", command=self.aes_encipher)
- self.menuTools.add_command(label="AES解密", command=self.aes_decipher)
- # "帮助"子菜单
- def helpsmenu(self):
- self.menuHelp.add_command(label="切换主题", command=self.themes)
- self.menuHelp.add_separator()
- self.menuHelp.add_command(label="关于", command=self.about)
- # 新窗口
- # def new(self, m=0):
- # main()
- # 结束程序
- def all_die(self, m=0):
- sys.exit()
- # 退出窗口(仅关闭一个窗口)
- def destroy(self, m=0):
- self.root.destroy()
- main()
复制代码
去看我AES加密那一部分.代码中有少量注释,勉强看看
第156~第177行 |
评分
-
查看全部评分
|