2018年8月2日17:02:00 【原创】
目录:python 编程博客 索引
最近打算使用 python3 写一个图形化的加密工具,使用 AES 加密
另外我的环境使用了 wxpython 图形化模块,安装方法也很简单
pip install wxpython
pip install pyinstaller
pip install pycryptodome
wxpython 已经更新到版本 4.0 了,在这里的小软件中的环境是可以兼容使用的
打包成文件
pyinstaller -F -w -i C:\Users\John\Desktop\pythonworkV4.0\icon.ico C:\Users\John\Desktop\pythonworkV4.0\setup.py
1. 选择自定义的密钥文件
2. 选择自定义的明文文件
3. 加密成密文并显示
4. 选择密文文件
5. 选择呢密钥文件
6. 进行解密并显示出明文
# coding:UTF-8
#pip3 install pycryptodome
import wx
import os
import random, sys
from Crypto.Cipher import AES
wildcard1 = u"文本文件 (*.txt)|*.txt|" \
"All files (*.*)|*.*"
wildcard2 = u"文本文件 (*.txt)|*.txt|" \
"All files (*.*)|*.*"
fileDir = os.getcwd()
class MultiTextFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, u"AES 加密工具",
size=(600, 400))
global filepath1, filepath2, filepath3, Key, Text
keysize = 0
fileDir = os.getcwd()
panel = wx.Panel(self, -1)
#panel.SetBackgroundColour('#c0c3c8')
#font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
font = wx.Font(9, wx.ROMAN, wx.NORMAL, wx.BOLD, False)
fontbt = wx.Font(9, wx.ROMAN, wx.NORMAL, wx.BOLD, False)
fontms = wx.Font(15, wx.ROMAN, wx.NORMAL, wx.NORMAL, False)
font.SetPointSize(9)
#vbox:纵向排列的容器
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add((-1, 5)) #预留15像素空白,vbox6此行开始
#st7:“密钥文件”
hbox8 = wx.BoxSizer(wx.HORIZONTAL)
st5 = wx.StaticText(panel, 0, label=u'密钥文件:', style=wx.TE_LEFT) #静态文本
st5.SetFont(font)
hbox8.Add(st5,proportion=0,flag=wx.LEFT|wx.RIGHT,border = 15) #静态文本的左右空间15
#filepath1: 密钥路径
filepath3 = wx.TextCtrl(panel, size=(1024,30))
hbox8.Add(filepath3,proportion=1,flag=wx.ALIGN_LEFT)
#btn3:“浏览一”
btn4 = wx.Button(panel, label=u'浏览', size=(70, 30))
btn4.SetFont(fontbt)
hbox8.Add(btn4,proportion=0,flag=wx.RIGHT|wx.LEFT, border=15) #按钮3的左右空间15
vbox.Add(hbox8, proportion=1,flag= wx.BOTTOM | wx.TOP, border=15) #三部分水平分布
#st3:明文文件
hbox6 = wx.BoxSizer(wx.HORIZONTAL)
st3 = wx.StaticText(panel, 0, label=u'明文文件:', style=wx.TE_LEFT) #静态文本
st3.SetFont(font)
hbox6.Add(st3,proportion=0,flag=wx.LEFT|wx.RIGHT,border = 15) #静态文本的左右空间15
#filepath1: 明文路径
filepath1 = wx.TextCtrl(panel, size=(1024,30))
hbox6.Add(filepath1,proportion=1,flag=wx.ALIGN_LEFT)
#btn3:“浏览上”
btn3 = wx.Button(panel, label=u'浏览', size=(70, 30))
btn3.SetFont(fontbt)
hbox6.Add(btn3,proportion=0,flag=wx.RIGHT|wx.LEFT, border=15) #按钮3的左右空间15
vbox.Add(hbox6, proportion=1,flag= wx.BOTTOM, border=10) #三部分水平分布
#vbox.Add((-1, 5)) #预留15像素空白
#st1:“明文”
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
#tc1: 明文文本框内容
#hbox1.Add(st1, flag=wx.RIGHT, border=10) #明文区域左空间
self.tc1 = wx.TextCtrl(panel,size=(400,70),style=wx.TE_MULTILINE | wx.TE_RICH2 )
self.tc1.SetFont(fontms)
hbox1.Add(self.tc1, proportion=1, flag=wx.EXPAND | wx.LEFT ,border=30)
vbox.Add(hbox1, proportion=1, flag= wx.RIGHT | wx.EXPAND, border=10) #明文区域右空间
#vbox.Add((-1, 5)) #预留15像素空白
#st4:“密文文件:”
hbox6 = wx.BoxSizer(wx.HORIZONTAL)
st4 = wx.StaticText(panel, 0, label=u'密文文件:', style=wx.TE_LEFT) #静态文本
st4.SetFont(font)
hbox6.Add(st4,proportion=0,flag=wx.LEFT|wx.RIGHT,border = 15) #静态文本的左右空间15
#filepath2: 密文路径
filepath2 = wx.TextCtrl(panel, size=(1024,30))
hbox6.Add(filepath2,proportion=1,flag=wx.ALIGN_LEFT)
#btn5:“浏览下””
btn5 = wx.Button(panel, label=u'浏览', size=(70, 30))
btn5.SetFont(fontbt)
hbox6.Add(btn5,proportion=0,flag=wx.RIGHT|wx.LEFT, border=15) #按钮3的左右空间15
vbox.Add(hbox6, proportion=1, flag= wx.BOTTOM | wx.TOP, border=15) #三部分水平分布
hbox3 = wx.BoxSizer(wx.HORIZONTAL)
#tc2: 密文文本框内容
self.tc2 = wx.TextCtrl(panel, size=(400,800),style=wx.TE_MULTILINE | wx.TE_RICH2 | wx.TE_READONLY) # wx.HSCROLL 不自动换行
self.tc2.SetFont(fontms)
hbox3.Add(self.tc2, proportion=1, flag=wx.EXPAND | wx.LEFT ,border=30)
vbox.Add(hbox3, proportion=1, flag= wx.RIGHT |wx.BOTTOM| wx.EXPAND,border=10) #密文区域右空间
hbox5 = wx.BoxSizer(wx.HORIZONTAL)
#btn1:"RSA加密"
btn1 = wx.Button(panel, label=u'加密', size=(110, 30))
btn1.SetFont(font)
hbox5.Add(btn1, flag=wx.LEFT , border=50)
#btn2:“RSA解密”
btn2 = wx.Button(panel, label=u'解密', size=(110, 30))
btn2.SetFont(font)
hbox5.Add(btn2, flag=wx.LEFT , border=50) #两个按钮中间空间
vbox.Add(hbox5, flag=wx.ALIGN_CENTER_HORIZONTAL, border=30) #三个按钮右空间
vbox.Add((-1, 15)) #预留15像素空白
panel.SetSizer(vbox)
'''绑定事件'''
#ipaddr: IP地址栏
#filepath1: 明文路径
#filepath2: 密文路径
#filepath3: 密钥路径
#tc1: 明文文本框内容
#tc2:密文文本框内容
self.Bind(wx.EVT_BUTTON, self.encryptMessage, btn1) #加密
self.Bind(wx.EVT_BUTTON, self.decryptMessage, btn2) #解密
self.Bind(wx.EVT_BUTTON, self.openplaintextfile, btn3) #浏览2
self.Bind(wx.EVT_BUTTON, self.openkeyfile, btn4) #浏览1
self.Bind(wx.EVT_BUTTON, self.openciphertextfile, btn5) #浏览3
#加密内容需要长达16位字符,所以进行空格拼接
def pad(self,Text):
#global Text
while len(Text) % 16 != 0:
Text += b' '
return Text
#加密秘钥需要长达16位字符,所以进行空格拼接
def pad_key(self,Key):
# global Key
while len(Key) % 16 != 0:
Key += b' '
return Key
def encryptMessage(self, event):
try:
#self.tc1.Clear()
self.tc2.Clear()
tc1data = self.tc1.GetValue()
#global Key
keyfile = filepath3.GetValue()
fo = open(keyfile)
Key = fo.read().encode('utf-8')
fo.close()
#print(Key)
#进行加密算法,模式ECB模式,把叠加完16位的秘钥传进来
aes = AES.new(self.pad_key(Key), AES.MODE_ECB)
#加密内容,此处需要将字符串转为字节
#Text = b'woshijiamineirong'
#global Text
msgfile = filepath1.GetValue()
fo = open(msgfile)
Text = fo.read().encode('utf-8')
fo.close()
#print(Text)
#进行内容拼接16位字符后传入加密类中,结果为字节类型
encrypted_text = aes.encrypt(self.pad(Text))
#print('密文:')
#print(encrypted_text)
cryptedfile = filepath2.GetValue()
fo = open(cryptedfile,'wb')
fo.write(encrypted_text)
fo.close()
crymsg = str(encrypted_text, encoding='utf8',errors="ignore")
self.tc2.SetValue(crymsg)
except FileNotFoundError:
messagedata = u'参数输入不正确'
dlg = wx.MessageDialog(self, messagedata, caption='提示', style = wx.OK|wx.ICON_ERROR)
dlg.ShowModal()
def decryptMessage(self, event):
self.tc1.Clear()
self.tc2.Clear()
tc2data = self.tc2.GetValue()
dlg6 = wx.FileDialog(
self,defaultFile="key.txt",
message=u"请选择密钥文件",
defaultDir=fileDir,
wildcard=wildcard1,
style=wx.FD_OPEN | wx.FD_MULTIPLE)
if dlg6.ShowModal() == wx.ID_OK:
dlg1 = wx.FileDialog(
self,defaultFile="encryted.txt",
message=u"请选择密文文件",
defaultDir=fileDir,
wildcard=wildcard1,
style=wx.FD_OPEN | wx.FD_MULTIPLE)
if dlg1.ShowModal() == wx.ID_OK:
if os.path.exists(dlg1.GetPath()) == True:
keyfile2 = dlg6.GetPath()
filepath3.SetValue(keyfile2)
msgfile2 = dlg1.GetPath()
filepath2.SetValue(msgfile2)
#此处是为了验证是否能将字节转为字符串后,进行解密成功
#实际上a 就是 encrypted_text ,也就是加密后的内容
#用aes对象进行解密,将字节类型转为str类型,错误编码忽略不计
#获取str从0开始到文本内容的字符串长度。
fo = open(msgfile2,'rb')
msg2 = fo.read()
fo.close()
msg22 = str(msg2, encoding='utf8',errors="ignore")
self.tc2.AppendText(msg22)
#print(msg2)
fo = open(keyfile2,'rb')
key2 = fo.read()
fo.close()
#print(key2)
aes = AES.new(self.pad_key(key2), AES.MODE_ECB)
de = str(aes.decrypt(msg2),encoding='utf-8',errors="ignore")
#print('明文:')
#print(de[:len(msg2)])
self.tc1.AppendText(de)
def openplaintextfile(self, event):
dlg = wx.FileDialog(
self,defaultFile="message.txt",
message=u"选择明文文件",
defaultDir=fileDir,
wildcard=wildcard1,
style=wx.FD_OPEN | wx.FD_MULTIPLE)
dlg.SetDirectory(fileDir)
if dlg.ShowModal() == wx.ID_OK:
tmp=""
paths = dlg.GetPaths()
for path in paths:
tmp=tmp+path
filepath1.SetValue(tmp)
file=open(filepath1.GetValue())
self.tc1.SetValue(file.read())
file.close()
#print('明文文件打开成功!')
#self.tc3.AppendText('\n明文文件打开成功!')
dlg.Destroy()
def openciphertextfile(self,event):
dlg = wx.FileDialog(
self,defaultFile="encryted.txt",
message=u"选择密文保存位置",
defaultDir=fileDir,
wildcard=wildcard1,
style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
if dlg.ShowModal() == wx.ID_OK:
tmp=""
paths = dlg.GetPaths()
for path in paths:
tmp=tmp+path
filepath2.SetValue(tmp)
dlg.Destroy()
def openkeyfile(self,event):
dlg = wx.FileDialog(
self,defaultFile="key.txt",
message=u"选择密钥文件",
defaultDir=fileDir,
wildcard=wildcard1,
style=wx.FD_OPEN | wx.FD_MULTIPLE)
dlg.SetDirectory(fileDir)
if dlg.ShowModal() == wx.ID_OK:
tmp=""
paths = dlg.GetPaths()
for path in paths:
tmp=tmp+path
filepath3.SetValue(tmp)
file=open(filepath3.GetValue())
global Key
Key = file.read().encode('utf-8')
file.close()
dlg.Destroy()
class MyApp(wx.App):
def __init__(self):
# 重构__init__方法,将错误信息重定位到文件中;
# 默认redirect=True,输出到StdOut或StdError;
# 为防止程序因错误一闪而过无法捕捉信息,可在
# 控制台中使用python -i example.py来运行程序。
wx.App.__init__(self, redirect=True)
def OnInit(self):
frame = MultiTextFrame()
frame.Show(True)
return True
def main():
app = MyApp()
app.MainLoop()
if __name__ == "__main__":
main()