[Python] 纯文本查看 复制代码
from Crypto.PublicKey import RSA
import tkinter as tk
from tkinter import messagebox,ttk,filedialog
import libnum
from Crypto.Util.number import *
import base64
import windnd
import os
import rsa
class Application(tk.Frame):
def __init__(self, root):
super().__init__(root)
self.master = root
self.key_file=''
self.pack()
self.fmt_var = tk.StringVar()
self.master.geometry("700x600+100+50")
# 设置窗口最小和最大尺寸
self.master.minsize(700, 600)
self.master.title("RSA秘钥解析")
self.intWind()
# 设置Text内容的函数
def setText(self, text, s):
text.delete(0.0, 'end')
text.insert(0.0, s)
# 解析RSA密钥
def dec_key(self):
# 从框中获取到RSA密钥字符串
rsakey = self.key_text.get(0.0, 'end').strip()
try:
# 导入字符串的字节码,获取解析后的key
key = RSA.importKey(rsakey.encode())
if (key.has_private()):
self.setText(self.type, "私钥")
self.setText(self.bits, str(key.size_in_bits()) + "位")
self.setText(self.e_text, key.e)
self.e = key.e
self.setText(self.n_text, key.n)
self.n = key.n
self.setText(self.d_text, key.d)
self.d = key.d
self.setText(self.p_text, key.p)
self.setText(self.q_text, key.q)
self.setText(self.phi_text, (key.p - 1) * (key.q - 1))
else:
self.setText(self.type, "公钥")
self.setText(self.bits, str(key.size_in_bits()) + "位")
self.setText(self.e_text, key.e)
self.e = key.e
self.setText(self.n_text, key.n)
self.n = key.n
except:
messagebox.showinfo("提示", "不是标准的密钥")
# 拖拽密钥文件解析
def draw_key(self,files):
self.key_file=files[0].decode('gbk')
self.importKey()
# 导入二进制的密钥文件解析
def importKey(self):
if self.key_file!='':
path_=self.key_file
else:
path_=filedialog.askopenfilename()
with open(path_,'rb') as f:
rsakey=f.read()
try:
# 导入字符串的字节码,获取解析后的key
key=RSA.importKey(rsakey)
if (key.has_private()):
if b'---' in rsakey:
self.setText(self.key_text,rsakey.decode())
else:
self.setText(self.key_text, "-----BEGIN RSA PRIVATE KEY-----\n" + base64.b64encode(
rsakey).decode() + "\n-----END RSA PRIVATE KEY-----")
self.setText(self.type, "私钥")
self.setText(self.bits, str(key.size_in_bits()) + "位")
self.setText(self.e_text, key.e)
self.e = key.e
self.setText(self.n_text, key.n)
self.n = key.n
self.setText(self.d_text, key.d)
self.d = key.d
self.setText(self.p_text, key.p)
self.setText(self.q_text, key.q)
self.setText(self.phi_text, (key.p - 1) * (key.q - 1))
else:
if b'---' in rsakey:
self.setText(self.key_text,rsakey.decode())
else:
self.setText(self.key_text, "-----BEGIN PUBLIC KEY-----\n" + base64.b64encode(
rsakey).decode() + "\n-----END PUBLIC KEY-----")
self.setText(self.type, "公钥")
self.setText(self.bits, str(key.size_in_bits()) + "位")
self.setText(self.e_text, key.e)
self.e = key.e
self.setText(self.n_text, key.n)
self.n = key.n
except:
messagebox.showinfo("提示", "不是标准的密钥")
# 明文加密方法
def enc_txt(self):
if self.fmt_var.get() == "16进制":
e = int(self.e_text.get(0.0, 'end').strip(), 16)
n = int(self.n_text.get(0.0, 'end').strip(), 16)
c = self.c_text.get(0.0, 'end').strip()
c = c.encode("utf-8")
pubkey=rsa.key.PublicKey(n,e)
m = rsa.encrypt(c,pubkey)
self.setText(self.m_text, base64.b64encode(m))
elif self.fmt_var.get() == "10进制":
e = int(self.e_text.get(0.0, 'end').strip())
n = int(self.n_text.get(0.0, 'end').strip())
c = self.c_text.get(0.0, 'end').strip()
c = c.encode("utf-8")
pubkey=rsa.key.PublicKey(n,e)
m = rsa.encrypt(c,pubkey)
self.setText(self.m_text, base64.b64encode(m))
else:
return 0
# 密文解密方法
def dec_txt(self):
if self.fmt_var.get() == "16进制":
n = int(self.n_text.get(0.0, 'end').strip(), 16)
d = int(self.d_text.get(0.0, 'end').strip(), 16)
e = int(self.e_text.get(0.0, 'end').strip(), 16)
p = int(self.p_text.get(0.0, 'end').strip(), 16)
q = int(self.q_text.get(0.0, 'end').strip(), 16)
m = self.m_text.get(0.0, 'end').strip()
privkey=rsa.key.PrivateKey(n,e,d,p,q)
c=rsa.decrypt(base64.b64decode(m),privkey).decode("utf-8")
self.setText(self.c_text, c)
elif self.fmt_var.get() == "10进制":
n = int(self.n_text.get(0.0, 'end').strip())
d = int(self.d_text.get(0.0, 'end').strip())
e = int(self.e_text.get(0.0, 'end').strip())
p = int(self.p_text.get(0.0, 'end').strip())
q = int(self.q_text.get(0.0, 'end').strip())
m = self.m_text.get(0.0, 'end').strip()
privkey=rsa.key.PrivateKey(n,e,d,p,q)
c=rsa.decrypt(base64.b64decode(m),privkey).decode("utf-8")
self.setText(self.c_text, c)
else:
return 0
# 清除所有框里的内容
def clear(self):
self.key_text.delete(0.0, 'end')
self.type.delete(0.0, 'end')
self.bits.delete(0.0, 'end')
self.e_text.delete(0.0, 'end')
self.n_text.delete(0.0, 'end')
self.d_text.delete(0.0, 'end')
self.p_text.delete(0.0, 'end')
self.q_text.delete(0.0, 'end')
self.phi_text.delete(0.0, 'end')
self.c_text.delete(0.0, 'end')
self.m_text.delete(0.0, 'end')
# 格式转换计算方法
def int_format(self, *args):
e = self.e_text.get(0.0, 'end').strip()
if e == '': e = '0'
n = self.n_text.get(0.0, 'end').strip()
if n == '': n = '0'
d = self.d_text.get(0.0, 'end').strip()
if d == '': d = '0'
p = self.p_text.get(0.0, 'end').strip()
if p == '': p = '0'
q = self.q_text.get(0.0, 'end').strip()
if q == '': q = '0'
phi = self.phi_text.get(0.0, 'end').strip()
if phi == '': phi = '0'
m = self.m_text.get(0.0, 'end').strip()
if m == '': m = '0'
if self.fmt_var.get() == "16进制":
self.setText(self.e_text, hex(int(e)))
self.setText(self.n_text, hex(int(n)))
self.setText(self.d_text, hex(int(d)))
self.setText(self.p_text, hex(int(p)))
self.setText(self.q_text, hex(int(q)))
self.setText(self.phi_text, hex(int(phi)))
self.setText(self.m_text, hex(int(m)))
if self.fmt_var.get() == "10进制":
self.setText(self.e_text, int(e, 16))
self.setText(self.n_text, int(n, 16))
self.setText(self.d_text, int(d, 16))
self.setText(self.p_text, int(p, 16))
self.setText(self.q_text, int(q, 16))
self.setText(self.phi_text, int(phi, 16))
self.setText(self.m_text, int(m, 16))
# 根据p、q计算出密钥其他参数
def calc_key(self):
if self.fmt_var.get() == "16进制":
p = int(self.p_text.get(0.0, 'end').strip(), 16)
q = int(self.q_text.get(0.0, 'end').strip(), 16)
e = self.e_text.get(0.0, 'end').strip()
# 如果e没有设置则默认为65537
if e == '':
e = 65537
else:
e = int(e, 16)
n = p * q
phi = (p - 1) * (q - 1)
# ed=1 mod phi 计算d
d = libnum.invmod(e, phi)
self.setText(self.e_text, hex(e))
self.setText(self.n_text, hex(n))
self.setText(self.d_text, hex(d))
self.setText(self.phi_text, hex(phi))
elif self.fmt_var.get() == "10进制":
p = int(self.p_text.get(0.0, 'end').strip())
q = int(self.q_text.get(0.0, 'end').strip())
e = self.e_text.get(0.0, 'end').strip()
if e == '':
e = 65537
else:
e = int(e)
n = p * q
phi = (p - 1) * (q - 1)
d = libnum.invmod(e, phi)
self.setText(self.e_text, e)
self.setText(self.n_text, n)
self.setText(self.d_text, d)
self.setText(self.phi_text, phi)
# 根据给定的密钥位数随机生成密钥
def geno_key(self):
if self.fmt_var.get() == "16进制":
bits = self.bits.get(0.0, 'end').strip()
e = self.e_text.get(0.0, 'end').strip()
if bits == '':
bits = 1024
self.setText(self.bits, bits)
else:
bits = int(bits)
if e == '' or '0x0':
e = 65537
else:
e = int(e, 16)
# 这里使用Crypto.Util.number.getPrime(n)也可以使用libnum.generate_prime(n)
p = getPrime(bits)
q = getPrime(bits)
n = p * q
phi = (p - 1) * (q - 1)
# 这里使用libnum.invmod()也可以使用 Crypto.Util.number.inverse()
d = libnum.invmod(e, phi)
self.setText(self.e_text, hex(e))
self.setText(self.n_text, hex(n))
self.setText(self.d_text, hex(d))
self.setText(self.p_text, hex(p))
self.setText(self.q_text, hex(q))
self.setText(self.phi_text, hex(phi))
elif self.fmt_var.get() == "10进制":
bits = self.bits.get(0.0, 'end').strip()
e = self.e_text.get(0.0, 'end').strip()
if bits == '':
bits = 1024
self.setText(self.bits, bits)
else:
bits = int(bits)
if e == '' or '0':
e = 65537
else:
e = int(e)
p = getPrime(bits)
q = getPrime(bits)
n = p * q
phi = (p - 1) * (q - 1)
d = libnum.invmod(e, phi)
self.setText(self.e_text, e)
self.setText(self.n_text, n)
self.setText(self.d_text, d)
self.setText(self.p_text, p)
self.setText(self.q_text, q)
self.setText(self.phi_text, phi)
# 分解N计算
def calc_N(self):
N=self.n_text2.get(0.0,'end').strip()
jg=''
t = os.popen(r"yafu-x64.exe factor({})".format(N)).readlines()
for i in t:
if i.startswith('P'):
jg=jg+'\n'+i.strip()
self.setText(self.jg_text2,jg.strip())
# 重新创建一个界面
def creatwindow(self):
# 重新船舰一个界面,上层是master界面
newwindow=tk.Toplevel(self.master)
# 设置新界面的标题
newwindow.title("N分解计算")
# 设置新界面的大小和偏移
newwindow.geometry("620x300+120+60")
# 在新界面上创建一个UI框架
N_frame = tk.Frame(newwindow)
tk.Label(N_frame, text=" n:").grid(row=0, column=0, pady=5)
self.n_text2 = tk.Text(N_frame, height=5, bg="#e3f9fd")
self.n_text2.grid(row=0, column=1, pady=5)
tk.Label(N_frame, text="结果:").grid(row=1, column=0, pady=5)
self.jg_text2 = tk.Text(N_frame, height=10, bg="#e3f9fd")
self.jg_text2.grid(row=1, column=1, pady=5)
N_frame.pack()
B_frame=tk.Frame(newwindow)
ttk.Button(B_frame, text="分解N", command=self.calc_N).grid(row=1, column=0, padx=10)
B_frame.pack()
# 设置UI布局
def intWind(self):
key_frame = tk.Frame(self)
tk.Label(key_frame, text="证书内容:").grid(row=0, column=0, pady=10)
tk.Button(key_frame, text="导入解析", command=self.importKey).grid(row=1, column=0)
self.key_text = tk.Text(key_frame, height=5)
self.key_text.grid(row=0, column=1, pady=10,rowspan=7)
key_frame.pack(anchor='w')
# 通过拖拽文件到key_fram组件处进行解析
windnd.hook_dropfiles(key_frame,func=self.draw_key)
type_frame = tk.Frame(self)
tk.Label(type_frame, text="证书类型:").grid(row=0, column=0, pady=5)
self.type = tk.Text(type_frame, height=1, width=6, bg="#bababa")
self.type.grid(row=0, column=1, pady=5)
tk.Label(type_frame, text=" ").grid(row=0, column=2, pady=5)
tk.Label(type_frame, text="证书位数:").grid(row=0, column=3, pady=5)
self.bits = tk.Text(type_frame, height=1, width=6, bg="#bababa")
self.bits.grid(row=0, column=4, pady=5)
tk.Label(type_frame, text=" ").grid(row=0, column=5, pady=5)
tk.Label(type_frame, text="进制:").grid(row=0, column=6, pady=5)
# 增加一个下拉选择框
self.fmt = ttk.Combobox(type_frame, textvariable=self.fmt_var, width=10)
# 设置下拉框的选项
self.fmt['value'] = ('10进制', '16进制')
# 设置下拉框的默认选项
self.fmt.current(0)
# 当下拉框内容变化是绑定一个方法
self.fmt.bind('<<ComboboxSelected>>', self.int_format)
self.fmt.grid(row=0, column=7, pady=5)
type_frame.pack(anchor='w')
e_frame = tk.Frame(self)
tk.Label(e_frame, text=" e:").grid(row=0, column=0, pady=5)
self.e_text = tk.Text(e_frame, height=1, bg="#e3f9fd")
self.e_text.grid(row=0, column=1, pady=5)
e_frame.pack(anchor='w')
n_frame = tk.Frame(self)
tk.Label(n_frame, text=" n:").grid(row=0, column=0, pady=5)
self.n_text = tk.Text(n_frame, height=3, bg="#e3f9fd")
self.n_text.grid(row=0, column=1, pady=5)
n_frame.pack(anchor='w')
d_frame = tk.Frame(self)
tk.Label(d_frame, text=" d:").grid(row=0, column=0, pady=5)
self.d_text = tk.Text(d_frame, height=3, bg="#a98175")
self.d_text.grid(row=0, column=1, pady=5)
d_frame.pack(anchor='w')
p_frame = tk.Frame(self)
tk.Label(p_frame, text=" p:").grid(row=0, column=0, pady=5)
self.p_text = tk.Text(p_frame, height=3, bg="#bababa")
self.p_text.grid(row=0, column=1, pady=5)
p_frame.pack(anchor='w')
q_frame = tk.Frame(self)
tk.Label(q_frame, text=" q:").grid(row=0, column=0, pady=5)
self.q_text = tk.Text(q_frame, height=3, bg="#bababa")
self.q_text.grid(row=0, column=1, pady=5)
q_frame.pack(anchor='w')
phi_frame = tk.Frame(self)
tk.Label(phi_frame, text=" phi(n):").grid(row=0, column=0, pady=5)
self.phi_text = tk.Text(phi_frame, height=3, bg="#bababa")
self.phi_text.grid(row=0, column=1, pady=5)
phi_frame.pack(anchor='w')
c_frame = tk.Frame(self)
tk.Label(c_frame, text=" 明文:").grid(row=0, column=0, pady=5)
self.c_text = tk.Text(c_frame, height=3)
self.c_text.grid(row=0, column=1, pady=5)
c_frame.pack(anchor='w')
m_frame = tk.Frame(self)
tk.Label(m_frame, text=" 密文:").grid(row=0, column=0, pady=5)
self.m_text = tk.Text(m_frame, height=3)
self.m_text.grid(row=0, column=1, pady=5)
m_frame.pack(anchor='w')
btn_frame = tk.Frame(self)
ttk.Button(btn_frame, text="解密证书", command=self.dec_key).grid(row=0, column=0, padx=10)
ttk.Button(btn_frame, text="用pq计算秘钥", command=self.calc_key).grid(row=0, column=1, padx=10)
ttk.Button(btn_frame, text="明文加密", command=self.enc_txt).grid(row=0, column=2, padx=10)
ttk.Button(btn_frame, text="密文解密", command=self.dec_txt).grid(row=0, column=3, padx=10)
ttk.Button(btn_frame, text="随机生成秘钥", command=self.geno_key).grid(row=0, column=4, padx=10)
ttk.Button(btn_frame, text="清空", command=self.clear).grid(row=0, column=5, padx=10)
ttk.Button(btn_frame, text="yafu分解N", command=self.creatwindow).grid(row=1, column=0, padx=10,pady=10)
btn_frame.pack()
if __name__ == "__main__":
root = tk.Tk()
app = Application(root)
app.mainloop()