zoukankan      html  css  js  c++  java
  • Python实现基于DES加密源码的文本加密器

    这是自行制作的一个DES文本加密工具

    最终效果图:

    本加密器支持UTF-8字符的加解密(包含中文),由于其中的编码方式与常用编码方式不同,加密结果与网上工具不同,但是能实现正常加解密。

    最终目标:

    目的是设计一个基于ECB模式,短块加密使用填充法的DES加密解密器,以此来实现对文本的加解密,其文本的处理还用到了base64编码。

    实验内容:

    des加密软件我采用的是python语言编写。主程序分了四个大的模块,

    一个负责图形化界面的编写及综合作用的mainfunc.py文件;

    一个负责DES的加解密的DES.py文件;

    一个负责字符串的处理以及base64编码的handle.py文件;

    最后一个setup.py用于打包程序

    以下将做详细介绍。

    首先来介绍软解加解密的主要流程

    对秘钥的处理:

      由于用户输入的秘钥是8个字符,故首先要将其转化为64位的二进制字符串,该功能由handle.py中的keyencode函数实现:

     

    加密流程:

    1用户输入的明文为任意字符串(包含中文字符以及英文字母以及标点符号),首先要进行分组处理,分组成64位二进制一组的二进制字符串,最后一组不足64位的使用填充法,该部分由handle.py中的encode函数处理

     

    2 接着根据之前得到的64位秘钥以及明文,依次进行DES加密,得到包含所有64位密文的数组

    3 接着要将各64位的密文连在一起得到二进制的密文字符串,再对其进行base64编码得到最终的输出字符串,该部分由handle.py中的base64encode函数处理。

     

    解密流程:

    1 解密首先要对得到的密文字符串进行反base64编码处理,去掉后面添加的‘=’,接着将其根据base64的编码规则转化为二进制字符串,然后去掉之前添加的‘0’字符,然后将字符串进行分组,分为64位一组。这一部分由handle.py中的base64decode函数完成。

     

    2接着根据之前得到的64位秘钥以及密文,依次进行DES解密,得到包含所有64位明文的数组。

    3接着要对得到的包含所有64位明文的数组进行处理,首先去掉之前填充的多余的字符,接着对二进制字符串进行反编码得到源字符串。该部分由handle.py中的decode函数得到。

     

    DES部分: 

    接着来编写DES加密模块,DES加解密流程完全按照书本上DES加解密流程实现,实现过程也没有什么难点,在此就不做过多介绍。

    实验难点:

     本次实验的DES加解密编程较为顺利,在字符串的操作上开始遇到了一点困难,之后比较顺利。主要是在字符串与二进制串的转换,字符编码上遇到了一些问题。

    1.填充法的选择

     由于初始的明文转化为64位二进制字符串后,最后一组并不一定是64位,故要进行处理,我这里运用的是比较直观的填充法,具体是PKCS5方法,在PKCS5方法中Block = 8bytesPadding特点:对于Block=8bytes(64bits)进行填充字节的值的取值范围在[1, 8].解码过程中,从最后一个字节看起,首先确定它表示的值1<=n<=8,然后检验最后n个字节的值是否相同,若相同最后删去最后n个字节即可得到完整的信息.特殊情况:若字符串恰好够分成完整的块,不多不少.则最后8个字节为:(IN HEX) 08 08 08 08 08 08 08 08

     我在代码中已经实现:

    2.中英文编码

       这个问题实则比较麻烦,在我使用的python2.7版本中默认英文字符占一个字节,即八位,中文字符占据两个字节,即两个字节。如果中英文混在一起将无法区分。

       一开始,我想到的解决方法是将中文字符16位中最高位置1,因为英文8位最高位为0,故可以将其区分,解码时在进行还原。但结果发现,有一部分中文字符最高位为0,故此法不通。

       因此,我只好将英文字符也扩展到16位,高8位置0,我最终的代码也按此实现,但是此方法对加密的安全性应该有一定的影响。例如,对于全英文的文本,所需要破解的字符串瞬间减到一半。

    但暂时没有想到更好的方法。

       以下为我的代码实现:

     

    附上最终源码:

    mainfunc.py

    #-*- coding=utf-8 -*-
    import wx
    import wx.lib.buttons as buttons
    from lib import DES
    from lib import handle
    
    class newframe(wx.Frame):
        def __init__(self):     #主框架
            wx.Frame.__init__(self,None,-1,u'DES加解密工具',size=(820,760),pos=(500,100))
            self.SetMinSize((820,760))
            self.SetMaxSize((820,760))
            self.panel=wx.Panel(self,-1)
            self.panelpic=wx.Image('./diary.jpg',wx.BITMAP_TYPE_JPEG,).Scale(820,760).ConvertToBitmap()
            self.picbk=wx.StaticBitmap(parent=self.panel,pos=(0,0),bitmap=self.panelpic)
            self.initstatictext()
            self.textctrl()
            self.buttoninit()
            self.buttonbind()
        def initstatictext(self):       #定义文本
            self.text1=wx.StaticText(self.picbk,-1,u'请输入加解密秘钥(仅八位长):',pos=(40,10),size=(-1,25),style=wx.TE_CENTER)#,size=(240,25))
            self.text2=wx.StaticText(self.picbk,-1,u'未加密文本:',pos=(40,60),size=(-1,25),style=wx.TE_CENTER)#,size=(240,25))
            self.text3=wx.StaticText(self.picbk,-1,u'加密后文本:',pos=(40,400),size=(-1,25),style=wx.TE_CENTER)#,size=(240,25))
            self.text1.SetBackgroundColour('AQUAMARINE')
            self.text2.SetBackgroundColour('AQUAMARINE')
            self.text3.SetBackgroundColour('AQUAMARINE')
        def textctrl(self):     #定义文本框
            font2 = wx.Font(12, wx.DECORATIVE, wx.NORMAL, wx.NORMAL)
            self.ctrl1=wx.TextCtrl(self.picbk,-1,'',pos=(30,100),size=(750,250), style=wx.TE_MULTILINE|wx.TE_RICH2)
            self.ctrl1.SetBackgroundColour('sky blue')
            self.ctrl1.SetFont(font2)
            self.ctrl2=wx.TextCtrl(self.picbk,-1,'',pos=(270,10),size=(150,28))
            self.ctrl2.SetBackgroundColour('sky blue')
            self.ctrl2.SetFont(font2)
            self.ctrl3=wx.TextCtrl(self.picbk,-1,'',pos=(30,450),size=(750,250), style=wx.TE_MULTILINE|wx.TE_RICH2)
            self.ctrl3.SetBackgroundColour('sky blue')
            self.ctrl3.SetFont(font2)
        def buttoninit(self):   #定义按钮
            self.button1=buttons.GenButton(self.picbk,-1,u'加密',pos=(240,380),size=(-1,50))
            self.button2=buttons.GenButton(self.picbk,-1,u'解密',pos=(540,380),size=(-1,50))
            self.button1.SetBezelWidth(5)
            self.button2.SetBezelWidth(5)
            self.button1.SetBackgroundColour("CORAL")
            self.button2.SetBackgroundColour("CORAL")
        def buttonbind(self):   #按钮事件绑定
            self.button1.Bind(wx.EVT_BUTTON,self.encode)
            self.button2.Bind(wx.EVT_BUTTON,self.decode)
        def encode(self,evt): #加密事件
            out=[]
            password=self.ctrl2.GetValue()
            password=handle.keyencode(password)
            text=self.ctrl1.GetValue()
            text=handle.encode(text)
            for one in text:
                a=DES.desencode(password,one)
                out.append(a)
            cipher=handle.base64encode(out)
            self.ctrl3.SetLabelText(cipher)
        def decode(self,evt): #解密事件
            cipherlist=[]
            outlist=[]
            password=self.ctrl2.GetValue()
            password=handle.keyencode(password)
            ciphertext=self.ctrl3.GetValue()
            cipherlist=handle.base64decode(ciphertext)
            for one in cipherlist:
                outlist.append(DES.desdecode(password,one))
            outstring=handle.decode(outlist)
            self.ctrl1.SetLabelText(outstring)
    
    if __name__=='__main__':
        newapp=wx.App(False)
        frame=newframe()
        frame.Show()
        newapp.MainLoop()
    

      handle.py

    #-*- coding=utf-8 -*-
    
    base='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    
    
    def keyencode(key):  #该部分将秘钥串转化为64位二进制形式
        out=''
        for i in key:   #将每一个字符转化为二进制形式
            out+=str(bin(ord(i))).replace('0b','').zfill(8)
        return out
    
    def encode(string):     #该部分主要是将明文字符串转化为每64位一组二进制明文
        out1=''
        text=[]
        for i in string:    #将每一个字符转化为二进制
            temp=str(bin(ord(i))).replace('0b','')
            out1+=temp.zfill(16)
        time=len(out1)/64
        for i in range(time+1): #对二进制字符串进行分组,每64位一组
            text.append(out1[64*i:64*(i+1)])
        length=len(text[time])
        if length!=64:    #最后一组如果不满64位进行填充
            add=8-length/8
            text[time]+=str(bin(ord(str(add)))).replace('0b','').zfill(8)*add
        else:
            text.append(str(bin(ord('8'))).replace('0b','').zfill(8)*8)
        return text
    
    def base64encode(list):  #该部分主要是对二进制串进行base64处理
        out=''
        string=''.join(list)
        a=len(string)%24
        if a==8:                #补0操作
            string+='0000'
        if a==16:
            string+='00'
        m=int(len(string)/6)
        for j in range(m):
            out+=base[int(string[j*6:j*6+6],2)]
        if(a==8):               #补=操作
            out+='=='
        if(a==16):
            out+='='
        return out
    
    def base64decode(string):   #该部分主要进行base64解码操作
        temp1=string.split('=')[0]  #去掉多余的=
        temp2=''
        outlist=[]
        for i in temp1:         #将字符串转化为二进制串
            temp2+=str(bin(base.index(i))).replace('0b','').zfill(6)
        temp3=len(temp2)
        if (temp3-2)%64==0:     #去掉多余的0
            temp2=temp2[0:len(temp2)-2]
        if (temp3-4)%64==0:
            temp2=temp2[0:len(temp2)-4]
        time=len(temp2)/64
        for i in range(time):   #将二进制串每64位进行分组
            outlist.append(temp2[64*i:64*(i+1)])
        return outlist
    
    def decode(list1):  #该部分主要是将64位明文转化为原字符串
        string=''
        more=int(chr(int(list1[len(list1)-1][56:64],2)))  #得到补充位数目
        strtemp1=''.join(list1)
        strtemp2=strtemp1[0:(len(strtemp1)-8*more)]  #去掉补充位
        for i in range(0,len(strtemp2)/8,2):
            if int(strtemp2[i*8:(i+1)*8],2)==0:  #如果此八位为0,则说明后面的一个字节为ascii编码
                string+=chr(int(strtemp2[(i+1)*8:(i+2)*8],2))
            else:       #如果此八位不为0,则说明该字节与后一个为unicode编码
                string+=unichr(int(strtemp2[i*8:(i+2)*8],2))
        return string
    

      DES.py

    # -*- coding: utf-8 -*-
    import time
    import base64
    import os
    
    m=0
    C0=''
    D0=''
    L0=''
    R0=''
    cipher=''
    outtext=''
    k=0
    
    substitute1=[57,49,41,33,25,17, 9,
                 1 ,58,50,42,34,26,18,
                 10, 2,59,51,43,35,27,
                 19,11, 3,60,52,44,36,
                 63,55,47,39,31,23,15,
                 7 ,62,54,46,38,30,22,
                 14, 6,61,53,45,37,29,
                 21,13, 5,28,20,12, 4]
    
    substitute2=[14,17,11,24, 1, 5, 3,28,
                 15, 6,21,10,23,19,12, 4,
                 26, 8,16, 7,27,20,13, 2,
                 41,52,31,37,47,55,30,40,
                 51,45,33,48,44,49,39,56,
                 34,53,46,42,50,36,29,32]
    
    shift=[1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]
    
    KEY=[ dict() for i in range(16)]
    
    sbox= [
            [
            0xe,0x4,0xd,0x1,0x2,0xf,0xb,0x8,0x3,0xa,0x6,0xc,0x5,0x9,0x0,0x7,
            0x0,0xf,0x7,0x4,0xe,0x2,0xd,0x1,0xa,0x6,0xc,0xb,0x9,0x5,0x3,0x8,
            0x4,0x1,0xe,0x8,0xd,0x6,0x2,0xb,0xf,0xc,0x9,0x7,0x3,0xa,0x5,0x0,
            0xf,0xc,0x8,0x2,0x4,0x9,0x1,0x7,0x5,0xb,0x3,0xe,0xa,0x0,0x6,0xd,
            ],
            [
            0xf,0x1,0x8,0xe,0x6,0xb,0x3,0x4,0x9,0x7,0x2,0xd,0xc,0x0,0x5,0xa,
            0x3,0xd,0x4,0x7,0xf,0x2,0x8,0xe,0xc,0x0,0x1,0xa,0x6,0x9,0xb,0x5,
            0x0,0xe,0x7,0xb,0xa,0x4,0xd,0x1,0x5,0x8,0xc,0x6,0x9,0x3,0x2,0xf,
            0xd,0x8,0xa,0x1,0x3,0xf,0x4,0x2,0xb,0x6,0x7,0xc,0x0,0x5,0xe,0x9,
            ],
            [
            0xa,0x0,0x9,0xe,0x6,0x3,0xf,0x5,0x1,0xd,0xc,0x7,0xb,0x4,0x2,0x8,
            0xd,0x7,0x0,0x9,0x3,0x4,0x6,0xa,0x2,0x8,0x5,0xe,0xc,0xb,0xf,0x1,
            0xd,0x6,0x4,0x9,0x8,0xf,0x3,0x0,0xb,0x1,0x2,0xc,0x5,0xa,0xe,0x7,
            0x1,0xa,0xd,0x0,0x6,0x9,0x8,0x7,0x4,0xf,0xe,0x3,0xb,0x5,0x2,0xc,
            ],
            [
            0x7,0xd,0xe,0x3,0x0,0x6,0x9,0xa,0x1,0x2,0x8,0x5,0xb,0xc,0x4,0xf,
            0xd,0x8,0xb,0x5,0x6,0xf,0x0,0x3,0x4,0x7,0x2,0xc,0x1,0xa,0xe,0x9,
            0xa,0x6,0x9,0x0,0xc,0xb,0x7,0xd,0xf,0x1,0x3,0xe,0x5,0x2,0x8,0x4,
            0x3,0xf,0x0,0x6,0xa,0x1,0xd,0x8,0x9,0x4,0x5,0xb,0xc,0x7,0x2,0xe,
            ],
            [
            0x2,0xc,0x4,0x1,0x7,0xa,0xb,0x6,0x8,0x5,0x3,0xf,0xd,0x0,0xe,0x9,
            0xe,0xb,0x2,0xc,0x4,0x7,0xd,0x1,0x5,0x0,0xf,0xa,0x3,0x9,0x8,0x6,
            0x4,0x2,0x1,0xb,0xa,0xd,0x7,0x8,0xf,0x9,0xc,0x5,0x6,0x3,0x0,0xe,
            0xb,0x8,0xc,0x7,0x1,0xe,0x2,0xd,0x6,0xf,0x0,0x9,0xa,0x4,0x5,0x3,
            ],
            [
            0xc,0x1,0xa,0xf,0x9,0x2,0x6,0x8,0x0,0xd,0x3,0x4,0xe,0x7,0x5,0xb,
            0xa,0xf,0x4,0x2,0x7,0xc,0x9,0x5,0x6,0x1,0xd,0xe,0x0,0xb,0x3,0x8,
            0x9,0xe,0xf,0x5,0x2,0x8,0xc,0x3,0x7,0x0,0x4,0xa,0x1,0xd,0xb,0x6,
            0x4,0x3,0x2,0xc,0x9,0x5,0xf,0xa,0xb,0xe,0x1,0x7,0x6,0x0,0x8,0xd,
            ],
            [
            0x4,0xb,0x2,0xe,0xf,0x0,0x8,0xd,0x3,0xc,0x9,0x7,0x5,0xa,0x6,0x1,
            0xd,0x0,0xb,0x7,0x4,0x9,0x1,0xa,0xe,0x3,0x5,0xc,0x2,0xf,0x8,0x6,
            0x1,0x4,0xb,0xd,0xc,0x3,0x7,0xe,0xa,0xf,0x6,0x8,0x0,0x5,0x9,0x2,
            0x6,0xb,0xd,0x8,0x1,0x4,0xa,0x7,0x9,0x5,0x0,0xf,0xe,0x2,0x3,0xc,
            ],
            [
            0xd,0x2,0x8,0x4,0x6,0xf,0xb,0x1,0xa,0x9,0x3,0xe,0x5,0x0,0xc,0x7,
            0x1,0xf,0xd,0x8,0xa,0x3,0x7,0x4,0xc,0x5,0x6,0xb,0x0,0xe,0x9,0x2,
            0x7,0xb,0x4,0x1,0x9,0xc,0xe,0x2,0x0,0x6,0xa,0xd,0xf,0x3,0x5,0x8,
            0x2,0x1,0xe,0x7,0x4,0xa,0x8,0xd,0xf,0xc,0x9,0x0,0x3,0x5,0x6,0xb,
            ]
        ]
    
    substituteip= [
            58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,
            62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
            57,49,41,33,25,17, 9,1,59,51,43,35,27,19,11,3,
            61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7]
    
    selectoperate=[
            32, 1, 2, 3, 4, 5,
            4 , 5, 6, 7, 8, 9,
            8 , 9,10,11,12,13,
            12,13,14,15,16,17,
            16,17,18,19,20,21,
            20,21,22,23,24,25,
            24,25,26,27,28,29,
            28,29,30,31,32, 1]
    
    substituteP=[
            16, 7,20,21,29,12,28,17,
            1 ,15,23,26, 5,18,31,10,
            2 ,8 ,24,14,32,27, 3, 9,
            19,13,30, 6,22,11, 4,25]
    
    resubstituteip=[
            40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31,
            38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,
            36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,
            34,2,42,10,50,18,58,26,33,1,41, 9,49,17,57,25]
    def before():
        global KEY,m,C0,D0,L0,R0,cipher,outtext,k
        KEY=[ dict() for i in range(16)]
        m=0
        C0=''
        D0=''
        L0=''
        R0=''
        cipher=''
        outtext=''
        k=0
    
    def handleraw(string):
        a=''
        for i in string:
            a+=bin(ord(i)).replace('0b','').zfill(8)
        return a
    
    def shiftleft(string,x):    #循环左移
        return string[-(len(string)-x):]+string[:x]
    
    def encodepassword1(x):     #秘钥置换选择
        global C0
        global D0
        for i in range(0,28):
            C0+=x[substitute1[i]-1]
        for j in range(28,56):
            D0+=x[substitute1[j]-1]
    
    
    def encodepassword2():  #秘钥处理主流程
        global k,C0,D0
        t=''
        if(k!=16):
            C0=shiftleft(C0,shift[k])
            D0=shiftleft(D0,shift[k])
            s=C0+D0
            for i in substitute2:
                t+=s[i-1]
            KEY[k]=t
            k+=1
            encodepassword2()
    
    def substituteIP(string):  #初始置换IP
        global L0,R0
        a=''
        for i in substituteip:
            a+=string[i-1]
        L0=a[:32]
        R0=a[-32:]
    
    def sboxoperate():   #S盒操作
        mid=''
        for i in selectoperate:
            mid+=R0[i-1]
        mid=str(bin(int(mid,2)^int(KEY[m-1],2)).replace('0b','').zfill(48))
        outraw=''
        for n in range(8):
            a=int(mid[6*n]+mid[6*n+5],2)
            b=int(mid[(6*n+1):(6*n+5)],2)
            outraw+=str(bin(int(str(sbox[n][a*16+b]),10)).replace('0b','').zfill(4))
        out=''
        for i in substituteP:
            out+=outraw[i-1]
        return out
    
    def encodemain():       #加密主流程
        global m,L0,R0,cipher
        m+=1
        a=L0
        L0=R0
        R0=str(bin(int(sboxoperate(),2)^int(a,2)).replace('0b','').zfill(32))
        if(m!=16):
            encodemain()
        else:
            b=R0+L0
            for i in resubstituteip:
                cipher+=b[i-1]
    
    def decodecircle():     #解密主流程
        global L0,R0,outtext,m
        a=R0
        R0=L0
        L0=str(bin(int(sboxoperate(),2)^int(a,2)).replace('0b','').zfill(32))
        m-=1
        if(m!=0):
            decodecircle()
        else:
            d=L0+R0
            decodetext=[0 for i in range(64)]
            for i in range(64):
                decodetext[substituteip[i]-1]=d[i]
            outtext=''.join(decodetext)
    
    def decoderesubstituteip(string):       #逆置换IP
        global R0,L0,m
        m=16
        a=[0 for i in range(64)]
        for i in range(64):
            a[resubstituteip[i]-1]=string[i]
        a=''.join(a)
        R0=a[:32]
        L0=a[-32:]
    
    def desencode(password,text):   #加密函数
        before()
        encodepassword1(password)
        encodepassword2()
        substituteIP(text)
        encodemain()
        return cipher
    
    def desdecode(password,encodetext): #解密函数
        before()
        encodepassword1(password)
        encodepassword2()
        decoderesubstituteip(encodetext)
        decodecircle()
        return outtext
    
    if __name__=='__main__':
        e=raw_input('This is a DES encrypt and decrypt function
     press 1 to encrypt, 2 to decrypt:')
        password=raw_input('please input the key:')
        encodepassword1(password)
        encodepassword2()
        print 'the KEY is:
    ',KEY
        if(e=='1'):
            text=raw_input('please input the text:')
            substituteIP(text)
            encodemain()
            print 'the cipher is:',cipher
        if(e=='2'):
            ciphertext=raw_input('please input the cipher:')
            decoderesubstituteip(ciphertext)
            decodecircle()
            print 'the decodetext is:',outtext
        os.system("pause")
    

      setup.py

    import py2exe
    from distutils.core import setup
    
    '''setup(windows=["mainfunc.py"])'''
    setup(
    windows = [{"script":"mainfunc.py", "icon_resources": [(1, "lock.ico")]} ]
    )
    

      

  • 相关阅读:
    Android 仿iPhone ListView拖动排序 按钮联动删除显示隐藏
    START WITH CONNECT BY PRIOR 链表查询
    pdf转图片
    HttpClient支持使用代理服务器以及身份认证
    easyui 1.3.3 中combotree post传参问题
    quartz Cron表达式
    lucene分词多种方法
    secureCRT命令大全
    tbschedule
    mysql 查询表
  • 原文地址:https://www.cnblogs.com/lomooo/p/6358329.html
Copyright © 2011-2022 走看看