python实现加密解密功能(GUI)

项目概述

        项目使用python和tkinter实现,能够实现对明文/密文的加解密,或对文本进行base64、url编码/解码。

需求分析

        实现多种常见的ctf加密/解密(编码/解码)方法,选择相应加密/解密(编码/解码)算法后,输入明文/密文,可以给出结果。算法包括凯撒密码、仿射密码、维吉尼亚密码、RSA密码、base64编码、纵栏式移项密码、url编码。

方案设计

总体方案设计

        理解常用的加密/解密(编码/解码)原理,用编程语言实现基本的算法功能,最后在实现图形化界面。

功能设计

        用python实现基本的算法功能。

界面设计

        用tkinter实现图形化。

项目实施计划

main函数,实现GUI

# 实现图形化,用户的输入口
import tkinter as tk
import tkinter.messagebox
import CaeCode
import AffiCode
import VigCode
import RSACode
import Base64
import DisCode
import URL


def coChoose():
    # 凯撒加密
    if codeVar.get() == 0:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        key = enKey.get('1.0', tk.END)
        key = key.strip()

        prin = CaeCode.Cae(1, text, key)
        buT.config(text=prin)

    # 仿射加密
    elif codeVar.get() == 1:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        a = enKey.get('1.0', '1.0 lineend')
        a = a.strip()

        b = enKey.get('2.0', '2.0 lineend')
        b = b.strip()

        prin = AffiCode.Aff(1, text, a, b)
        buT.config(text=prin)

    # 维吉尼亚加密
    elif codeVar.get() == 2:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        key = enKey.get('1.0', tk.END)
        key = key.strip()

        prin = VigCode.Vig(1, text, key)
        buT.config(text=prin)

    # RSA加密
    elif codeVar.get() == 3:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        p = enKey.get('1.0', '1.0 lineend')
        p = p.strip()

        q = enKey.get('2.0', '2.0 lineend')
        q = q.strip()

        e = enKey.get('3.0', '3.0 lineend')
        e = e.strip()

        prin = RSACode.RSA(1, text, p, q, e)
        buT.config(text=prin)

    # Base64编码
    elif codeVar.get() == 4:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        prin = Base64.Base(1, text)
        buT.config(text=prin)

    # 纵栏式移项加密
    elif codeVar.get() == 5:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        key = enKey.get('1.0', tk.END)
        key = key.strip()

        prin = DisCode.Dis(1, text, key)
        buT.config(text=prin)

    # url编码
    elif codeVar.get() == 6:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        prin = URL.url(1, text)
        buT.config(text=prin)


def deChoose():
    # 凯撒解密
    if codeVar.get() == 0:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        key = enKey.get('1.0', tk.END)
        key = key.strip()

        prin = CaeCode.Cae(2, text, key)
        buT.config(text=prin)

    # 仿射解密
    elif codeVar.get() == 1:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        a = enKey.get('1.0', '1.0 lineend')
        a = a.strip()

        b = enKey.get('2.0', '2.0 lineend')
        b = b.strip()

        prin = AffiCode.Aff(2, text, a, b)
        buT.config(text=prin)

    # 维吉尼亚解密
    elif codeVar.get() == 2:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        key = enKey.get('1.0', tk.END)
        key = key.strip()

        prin = VigCode.Vig(2, text, key)
        buT.config(text=prin)

    # RSA解密
    elif codeVar.get() == 3:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        p = enKey.get('1.0', '1.0 lineend')
        p = p.strip()

        q = enKey.get('2.0', '2.0 lineend')
        q = q.strip()

        e = enKey.get('3.0', '3.0 lineend')
        e = e.strip()

        prin = RSACode.RSA(2, text, p, q, e)
        buT.config(text=prin)

    # Base64编码
    elif codeVar.get() == 4:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        prin = Base64.Base(2, text)
        buT.config(text=prin)

    # 纵栏式移项解密
    elif codeVar.get() == 5:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        key = enKey.get('1.0', tk.END)
        key = key.strip()

        prin = DisCode.Dis(2, text, key)
        buT.config(text=prin)

    # url解码
    elif codeVar.get() == 6:
        text = enText.get('1.0', tk.END)
        text = text.strip()

        prin = URL.url(2, text)
        buT.config(text=prin)


def helpCommand():
    tk.messagebox.showinfo('帮助(H)', '使用仿射密码时,密钥从上往下分别输入a,b\n'
                           + '使用RSA密码时,从上往下分别为p,q,e')


# 主窗口及格式
window = tk.Tk()
window.title('加解密工具')
window.configure(background='White')

width = 800
height = 600
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()
size_geo = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
window.geometry(size_geo)

window.resizable(width=False, height=False)

# 密码编码选项框架
coFrame = tk.Frame(window, bg='white')
coFrame.grid(padx=15, pady=10, row=0, column=0, rowspan=3)

codeVar = tk.IntVar()

code1 = tk.Radiobutton(coFrame, text="凯撒密码", bg='white', variable=codeVar, value=0)
code1.grid(ipadx=20, ipady=15, row=0, column=0)

code2 = tk.Radiobutton(coFrame, text="仿射密码", bg='white', variable=codeVar, value=1)
code2.grid(ipadx=20, ipady=15, row=1, column=0)

code3 = tk.Radiobutton(coFrame, text="维吉尼亚密码", bg='white', variable=codeVar, value=2)
code3.grid(ipadx=20, ipady=15, row=2, column=0)

code4 = tk.Radiobutton(coFrame, text="RSA密码", bg='white', variable=codeVar, value=3)
code4.grid(ipadx=20, ipady=15, row=3, column=0)

code5 = tk.Radiobutton(coFrame, text="Base64", bg='white', variable=codeVar, value=4)
code5.grid(ipadx=20, ipady=15, row=4, column=0)

code6 = tk.Radiobutton(coFrame, text="纵栏式移项密码", bg='white', variable=codeVar, value=5)
code6.grid(ipadx=20, ipady=15, row=5, column=0)

code7 = tk.Radiobutton(coFrame, text="url编码", bg='white', variable=codeVar, value=6)
code7.grid(ipadx=20, ipady=15, row=6, column=0)

# 输入输出框架
entry = tk.Frame(window, bg='white')
entry.grid(padx=15, pady=10, row=0, column=3)

enLabel = tk.Label(entry, text='请输入文本:', bg='white')
enLabel.grid(ipadx=20, ipady=15, row=0, column=0)

enText = tk.Text(entry, width=30, height=7)
enText.grid(ipadx=20, ipady=15, row=1, column=0)

enLabel = tk.Label(entry, text='请输入密钥:', bg='white')
enLabel.grid(ipadx=20, ipady=15, row=2, column=0)

enKey = tk.Text(entry, width=30, height=7)
enKey.grid(ipadx=20, ipady=15, row=3, column=0)

# 加密解密选项
edVar = tk.IntVar()
en = tk.Button(window, text='加密(编码)', bg='white', command=coChoose)
en.grid(padx=10, pady=5, row=0, column=4)

de = tk.Button(window, text='解密(解码)', bg='white', command=deChoose)
de.grid(padx=10, pady=5, row=1, column=4)

# 输出结果
buT = tk.Label(window, text='')
buT.grid(row=5, column=3)

# 菜单
mainmenu = tk.Menu(window)

mainmenu.add_command (label="文件")
mainmenu.add_command (label="编辑")
mainmenu.add_command (label="格式")
mainmenu.add_command (label="查看")
mainmenu.add_command (label="帮助",command=helpCommand)

# 显示菜单
window.config (menu=mainmenu)

window.mainloop()

算法

凯撒密码

# 实现凯撒密码
# 小写字典
lowDict = ['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']
# 大写字典
capDict = ['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']


# 将字母转换成数字
def switch(ele):
    flag = 0
    if ele.isalpha():
        if ele in lowDict:
            ele = lowDict.index(ele)
        elif ele in capDict:
            ele = capDict.index(ele)
            flag = 1

    return [int(ele), flag]


# beState 处理前  afState 处理后
# 加解密算法
def algo(choose, beState, key):
    afState = ''

    # key返回的flag值是没用的
    [k, flag] = switch(key)

    for i in beState:
        [be, flag] = switch(i)

        # 加密
        if choose == 1:
            af = (be + k) % 26

        # 解密
        if choose == 2:
            af = (be - k) % 26

        if flag == 0:
            afState += lowDict[af]
        else:
            afState += capDict[af]

    return afState


def Cae(choose, text, key):
    # 加密
    if choose == 1:
        plai = text

        return algo(choose, plai, key)

    # 解密
    elif choose == 2:
        ciph = text

        return algo(choose, ciph, key)

仿射密码

# 实现仿射密码
import math

# 小写字典
lowDict = ['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']
# 大写字典
capDict = ['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']


def switch(ele):  # 将字母转换成数字
    flag = 0
    if ele.isalpha():
        if ele in lowDict:
            ele = lowDict.index(ele)
        elif ele in capDict:
            ele = capDict.index(ele)
            flag = 1
    return [int(ele), flag]


# beState 处理前  afState 处理后
def algo(choose, beState, a, b):  # 加解密算法
    afState = ''
    [a, flag] = switch(a)
    [b, flag] = switch(b)
    if math.gcd(a, 26) != 1 or b < 0 or b >= 26:  # 判断输入的密钥格式
        print('你输入的密钥不符合算法格式')
        return False
    else:
        for i in beState:
            [be, flag] = switch(i)

            # 加密
            if choose == 1:
                af = (a * be + b) % 26

            # 解密
            elif choose == 2:
                inva = int(math.pow(a, 11))
                af = inva * (be - b) % 26
            if flag == 0:
                afState += lowDict[af]
            else:
                afState += capDict[af]
        return afState


def Aff(choose, text, a, b):
    if choose == 1:
        plai = text
        ciph = algo(choose, plai, a, b)
        if ciph is False:
            return '你输入的密钥不符合算法格式(a应与26互素)'
        else:
            return ciph

    elif choose == 2:
        ciph = text
        plai = algo(choose, ciph, a, b)
        if plai is False:
            return '你输入的密钥不符合算法格式(a应与26互素)'
        else:
            return plai

维吉尼亚密码

# 实现维吉尼亚密码
# 小写字典
lowDict = ['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']
# 大写字典
capDict = ['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']


# 将字母转换成数字
def switch(ele):
    flag = 0
    if ele in lowDict:
        ele = lowDict.index(ele)
    elif ele in capDict:
        ele = capDict.index(ele)
        flag = 1
    return [int(ele), flag]


# beState 处理前  afState 处理后
  # 加解密算法
def algo(choose, beState, key):

    # 判断密钥格式
    for i in key:
        if not i.isalpha():
            print('密钥格式应为英文字母')
            return False

    afState = ''

    # 用来补齐key和遍历ciph
    i = 0

    # 用来遍历key
    j = 0

    # 补齐key
    lenBeState = len(beState)
    lenKey = len(key)

    while lenKey < lenBeState:
        key += key[i]
        lenKey = len(key)
        i += 1

    # 加解密算法
    for i in beState:
        # 遍历key
        [k, flag] = switch(key[j])
        j += 1
        [be, flag] = switch(i)

        # 加密
        if choose == 1:
            af = (be + k) % 26

        # 解密
        elif choose == 2:
            af = (be - k) % 26

        if flag == 0:
            afState += lowDict[af]
        else:
            afState += capDict[af]

    return afState


# 主函数
def Vig(choose, text, key):
    # 加密
    if choose == 1:
        plai = text
        ciph = algo(choose, plai, key)
        if ciph is False:
            return '你输入的密钥不符合算法格式(密钥格式应为英文字母)'
        else:
            return ciph

    # 解密
    elif choose == 2:
        ciph = text
        plai = algo(choose, ciph, key)
        if plai is False:
            return '你输入的密钥不符合算法格式(密钥格式应为英文字母)'
        else:
            return plai

RSA密码

# 实现RSA密码
import math


# 判断是否为素数
def isPrime(num):
    for i in range(2, num):
        if num % i == 0:
            return False

    return True


def RSA(choose, text, p, q, e):
    text = int(text)
    p = int(p)
    q = int(q)
    e = int(e)

    # 加密
    if choose == 1:
        if not isPrime(p):
            return '你输入的p不是素数'

        if not isPrime(q):
            return '你输入的q不是素数'

        n = p * q
        phiN = (p - 1) * (q - 1)

        # 判断e与φ(n)是否互素
        if math.gcd(e, phiN) != 1:
            falE = '你输入的e与φ(n)不互素\n' \
                   + 'n = ' + str(n) + '\n' \
                   + 'φ(n) = ' + str(phiN)

            return falE

        # 计算e的逆元d
        k = 1
        while (k * phiN + 1) % e != 0:
            k += 1
        d = int((k * phiN + 1) / e)

        plai = text
        ciph = pow(plai, e, n)
        tru = 'n = ' + str(n) + '\n' \
              + 'φ(n) = ' + str(phiN) + '\n' \
              + 'd = ' + str(d) + '\n' \
              + '密文是' + str(ciph)

        return tru

    # 解密
    elif choose == 2:
        if not isPrime(p):
            return '你输入的p不是素数'

        if not isPrime(q):
            return '你输入的q不是素数'

        n = p * q
        phiN = (p - 1) * (q - 1)

        # 判断e与φ(n)是否互素
        if math.gcd(e, phiN) != 1:
            falE = '你输入的e与φ(n)不互素\n' \
                   + 'n = ' + str(n) + '\n' \
                   + 'φ(n) = ' + str(phiN)

            return falE

        # 计算e的逆元d
        k = 1
        while (k * phiN + 1) % e != 0:
            k += 1
        d = int((k * phiN + 1) / e)

        ciph = text
        plai = pow(ciph, d, n)
        tru = 'n = ' + str(n) + '\n' \
              + 'φ(n) = ' + str(phiN) + '\n' \
              + 'd = ' + str(d) + '\n' \
              + '明文是' + str(plai)

        return tru

Base64编码

# 实现Base64编码
# A - Z: 65 - 90  a - z: 97 - 122

# Base64索引表 + '='
Base64 = ['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',
          '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', '+', '/', '=']


def Base(choose, text):
    if choose == 1:
        tru = ''
        # 二进制形式
        binary = []

        # 将文本转换成对应的ASCII编码,再转换成二进制位
        for i in text:
            num = ord(i)
            # div: 除数  re: 余数  ele: 单个字母二进制元素
            div = 1
            ele = []

            while div != 0:
                div = num // 2
                re = num % 2
                num = div
                ele.append(re)

            # 单个字节补齐8位
            while len(ele) < 8:
                ele.append(0)
            ele.reverse()
            binary += ele

        # 每3个字节补齐24位
        while len(binary) % 24 != 0:
            binary.append(0)

        # 每6位二进制数为一个Base64编码索引
        while binary != []:
            flag = 0
            num = ''
            while flag < 6:
                num += str(binary.pop(0))
                flag += 1
            index = int(num, 2)

            # 判断全0索引是'A'还是'='
            if index == 0 and 1 not in binary:
                index = 64
            tru += Base64[index]
            tru += ''

        return tru

    # 解码
    elif choose == 2:
        tru = ''
        coding = text
        binary = []

        for i in coding:
            index = Base64.index(i)
            if index != 64:
                div = 1
                ele = []

                while div != 0:
                    div = index // 2
                    re = index % 2
                    index = div
                    ele.append(re)

                # 单个字节补齐6位
                while len(ele) < 6:
                    ele.append(0)
                ele.reverse()

            else:
                ele = [0, 0, 0, 0, 0, 0]
            binary += ele

        while binary != []:
            flag = 0
            num = ''
            while flag < 8:
                num += str(binary.pop(0))
                flag += 1
            index = int(num, 2)

            # 判断全0索引是'A'还是'='
            if index == 0 and 1 not in binary:
                break
            tru += chr(index)
            tru += ''

        return tru

纵栏式移项密码

# 实现纵栏式移项密码
# 小写字典
lowDict = ['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']
# 大写字典
capDict = ['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']


# 将字母转换成数字
def switch(ele):
    flag = 0
    if ele in lowDict:
        ele = lowDict.index(ele)
    elif ele in capDict:
        ele = capDict.index(ele)
        flag = 1
    return [int(ele), flag]


def Dis(choose, text, key):
    dict = {}
    lis = ''
    text = list(text)

    # 加密
    if choose == 1:
        while text != []:
            for i in key:
                [ele, flag] = switch(i)

                # 添加字典
                dict.setdefault(ele, '')
                if text == []:
                    break

                # 置换
                else:
                    temp = dict[ele] + text.pop(0)
                    dict[ele] = temp

        # 排序
        while dict != {}:
            minindex = min(dict.keys())
            lis += dict[minindex]
            dict.pop(minindex)

        return lis

    # 解密
    elif choose == 2:
        textNum = len(text)
        keyNum = len(key)

        # num用于计算每个数组的个数
        num = textNum // keyNum

        # re用于计算多余的字符
        re = textNum % keyNum

        while text != []:
            for i in key:
                [ele, flag] = switch(i)
                dict.setdefault(ele, '')

                # 置换
                if re != 0:
                    dict[ele] = text[0:num+1]
                    re -= 1
                    for j in range(0, num+1):
                        text.pop(0)
                else:
                    dict[ele] = text[0:num]
                    for j in range(0, num):
                        text.pop(0)

        # 排序
        tempList = sorted(dict.keys())
        tempLen = len(tempList)

        while tempLen > 0:
            for i in tempList:
                if dict[i] == []:
                    tempLen -= 1
                elif dict[i] != []:
                    lis += dict[i][0]
                    dict[i] = dict[i][1:]

        return lis

url编码

注:url解码部分有问题

# 实现url编码
# 保留字符的编码字典
endict = {'!': '%21', '#': '%23', '$': '%24', '&': '%26', "'": '%27', '(': '%28',
          ')': '%29', '*': '%2A', '+': '%2B', ',': '%2C', '/': '%2F', ':': '%3A',
          ';': '%3B', '=': '%3D', '?': '%3F', '@': '%40', '[': '%5B', ']': '%5D'}

# 反编码字典
dedict = {'21': '!', '23': '#', '24': '$', '26': '&', '27': "'", '28': '(',
          '29': ')', '2A': '*', '2B': '+', '2C': ',', '2F': '/', '3A': ':',
          '3B': ';', '3D': '=', '3F': '?', '40': '@', '5B': '[', '5D': ']'}


def url(choose, text):
    list = ''
    # 编码
    if choose == 1:
        for i in text:
            word = i
            if i in endict.keys():
                word = endict[i]
            list += word
        return list

    # 反编码
    elif choose == 2:
        text = text.split('%')
        for i in text:
            if i in dedict.keys():
                list += dedict[i]
            elif text.index(i) == 0:
                list += i
            else:
                list += '%'
                list += i
        return list

总结

        GUI部分做得很烂,实现图形化是我的一生之敌。部分算法本来不需要做得很复杂,例如凯撒密码,但为了统一输入输出,就稍微改多了一点(也是为了蹭代码行数),url解码部分因为时间紧急,做得不是很好。

你可能感兴趣的:(python,开发语言)