93 lines
3.6 KiB
Python
93 lines
3.6 KiB
Python
import tkinter as tk
|
|
from tkinter import messagebox
|
|
from Crypto.Cipher import AES, Blowfish
|
|
import binascii
|
|
|
|
class NavicatPassword:
|
|
def __init__(self):
|
|
self.aes_key = b'libcckeylibcckey'
|
|
self.aes_iv = b'libcciv libcciv '
|
|
|
|
def decrypt(self, encrypted_str):
|
|
try:
|
|
data = binascii.unhexlify(encrypted_str.lower())
|
|
cipher = AES.new(self.aes_key, AES.MODE_CBC, self.aes_iv)
|
|
decrypted = cipher.decrypt(data)
|
|
# 处理填充字符和不可打印字符
|
|
# 去除填充字符和控制字符
|
|
decrypted = decrypted.rstrip(b'\x00\x03\x04\x05')
|
|
|
|
# 过滤掉控制字符(0x00-0x1F),保留可打印字符
|
|
decrypted = bytes(b for b in decrypted if b >= 32 or b == 9 or b == 10 or b == 13)
|
|
|
|
# 尝试多种编码方式
|
|
encodings = ['utf-8', 'latin1', 'cp1252', 'gbk', 'big5']
|
|
for encoding in encodings:
|
|
try:
|
|
decoded = decrypted.decode(encoding)
|
|
# 保留所有可打印字符
|
|
return decoded
|
|
except UnicodeDecodeError:
|
|
continue
|
|
# 最后尝试,替换无法解码的字符
|
|
return decrypted.decode('latin1', errors='replace')
|
|
except Exception as e:
|
|
raise ValueError(f"解密失败: {str(e)}")
|
|
|
|
class App:
|
|
def __init__(self, root):
|
|
self.root = root
|
|
self.root.title("Navicat密码解密工具")
|
|
self.result_window = None # 用于存储结果窗口
|
|
|
|
self.password = tk.StringVar()
|
|
self.create_widgets()
|
|
|
|
def create_widgets(self):
|
|
tk.Label(self.root, text="加密密码:").grid(row=0, column=0, padx=5, pady=5)
|
|
tk.Entry(self.root, textvariable=self.password, width=30).grid(row=0, column=1, padx=(0, 10))
|
|
|
|
tk.Button(self.root, text="解密", command=self.decrypt_password).grid(row=1, column=1, pady=10)
|
|
|
|
def show_result(self, result):
|
|
# 如果结果窗口已经存在,则先销毁
|
|
if self.result_window is not None:
|
|
self.result_window.destroy()
|
|
|
|
self.result_window = tk.Toplevel(self.root)
|
|
self.result_window.title("解密结果")
|
|
|
|
tk.Label(self.result_window, text="解密后的密码:").pack(padx=20, pady=5)
|
|
|
|
# 使用更通用的字体,添加字体回退
|
|
font_family = ('Consolas', 'Courier New', 'Monaco', 'DejaVu Sans Mono')
|
|
font_size = 12
|
|
result_text = tk.Text(self.result_window, height=1, width=30, font=(font_family[0], font_size))
|
|
result_text.insert(tk.END, result)
|
|
result_text.config(state=tk.DISABLED)
|
|
result_text.pack(padx=20, pady=5)
|
|
|
|
def copy_to_clipboard():
|
|
self.root.clipboard_clear()
|
|
self.root.clipboard_append(result)
|
|
|
|
tk.Button(self.result_window, text="复制密码", command=copy_to_clipboard).pack(pady=10)
|
|
|
|
def decrypt_password(self):
|
|
password = self.password.get().strip()
|
|
if not password:
|
|
messagebox.showerror("错误", "请输入加密密码")
|
|
return
|
|
|
|
try:
|
|
navicat = NavicatPassword()
|
|
result = navicat.decrypt(password)
|
|
self.show_result(result)
|
|
except Exception as e:
|
|
messagebox.showerror("错误", f"解密失败:{str(e)}")
|
|
|
|
if __name__ == "__main__":
|
|
root = tk.Tk()
|
|
app = App(root)
|
|
root.mainloop()
|