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()