DES 加解密 python实现

DES加密算法原理及代码实现_des算法代码-CSDN博客

DES加解密(详细的加密流程)_des加密解密原理及流程-CSDN博客

参考这两篇实现的,第一篇讲解比较详细,第二篇的例子和老师作业的例子相同

根据多个已确定的矩阵,对明文做多次置换得到的密文,过程较繁琐,当个模拟题做了

对于数据补全的内容没有实现,若以后有机会再补充

DES加密看似复杂,实则一点也不简单,对于其加密、破解过程理解依然肤浅,需进一步学习

'''
auther:Poppy
time:2024/4/25
'''
IP = [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]

IP_1 = [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]

PC1 = [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]

PC2 = [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]

E = [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]

P = [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]

key = [[] for i in range(17)]
s = [[] for i in range(10)]

s[1] = [[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
        [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
        [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
        [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]]

s[2] = [[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
        [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
        [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
        [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]]

s[3] = [[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
        [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
        [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
        [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]]

s[4] = [[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
        [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
        [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
        [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]]

s[5] = [[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
        [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
        [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
        [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]]

s[6] = [[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
        [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
        [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
        [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]]

s[7] = [[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
        [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
        [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
        [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]]

s[8] = [[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
        [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
        [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
        [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]


def hex2Bin(x):
    tmp = ''
    for i in range(len(x)):
        tmp += '{:04b}'.format(int(x[i], 16))
    return tmp


def initData():
    global oriString, oriKey, encod
    encod = 1
    print('输入1测试作业,输入其他数字测试其他明文')

    type = int(input())
    if type == 1:
        oriString = '0123456789ABCDEF'
        print('明文为', oriString)
        oriString = hex2Bin(oriString)
        oriKey = '133457799BBCDFF1'
        print('密钥为', oriKey)
        oriKey = hex2Bin(oriKey)
    else:
        print('选择进制,二进制输入bin或2,16进制输入hex或16')
        tmp = input()
        if tmp == 'bin' or tmp == '2':
            print('请输入64位2进制数作为明文')
            oriString = input()
            print('请输入64位2进制数作为密钥')
            oriKey = input()
        elif tmp == 'hex' or tmp == '16':
            print('请输入16位16进制数作为明文')
            oriString = input()
            oriString = hex2Bin(oriString)
            print('请输入16位16进制数作为密钥')
            oriKey = input()
            oriKey = hex2Bin(oriKey)
        print('加密请输入1,解密请输入2')
        while True:
            encod = int(input())
            if encod in [1, 2]:
                break
            else:
                print('输入错误,请输入1或2')


def initPermutation():
    global L0, R0
    tmp = [''] * 64
    for i in range(64):
        tmp[i] = oriString[IP[i] - 1]
    L0, R0 = ''.join(tmp[:32]), ''.join(tmp[32:])


def get16Key():
    # 去除8个校验位
    tmp1 = ''
    for i in range(56):
        tmp1 += oriKey[PC1[i] - 1]

    # test
    # tmp1 = '11110000110011001010101011110101010101100110011110001111'

    C0, D0 = ''.join(tmp1[:28]), ''.join(tmp1[28:])
    q = [1, 2, 9, 16]
    lt, rt = C0, D0
    # 循环左移
    for i in range(1, 17):
        dx = 2
        if i in q:
            dx = 1
        lt = lt[dx:] + lt[:dx]
        rt = rt[dx:] + rt[:dx]
        # 进行pc2置换
        res = lt + rt
        ke = ''
        for j in range(48):
            ke += res[PC2[j] - 1]
        key[i] = ke


def fiter():
    global cip
    dx = 6
    l, r = L0, R0

    # 加解密处理
    if encod == 1:
        q = [i for i in range(1, 17)]
    elif encod == 2:
        q = [i for i in range(16, 0, -1)]

    for i in q:
        # E拓展
        tmpe = ''
        for j in range(48):
            tmpe += r[E[j] - 1]
        # 与对应密钥异或
        tmpxor = ''
        for j in range(48):
            tmpxor += str(int(tmpe[j]) ^ int(key[i][j]))
        # S盒代替
        tmps = ''
        for j in range(8):
            tmp = tmpxor[j * dx:j * dx + dx]
            x = int(tmp[0] + tmp[-1], 2)
            y = int(tmp[1:-1], 2)
            tmps += '{:04b}'.format(s[j + 1][x][y])
        # P盒置换
        tmpp = ''
        for j in range(32):
            tmpp += tmps[P[j] - 1]
        tmplxor = ''
        for j in range(32):
            tmplxor += str(int(tmpp[j]) ^ int(l[j]))
        l = r
        r = tmplxor
    nd = r + l
    cip = ''
    for i in range(64):
        cip += nd[IP_1[i] - 1]


def printCipher():
    print('二进制密文为:')
    for i in range(64):
        if i % 4 == 0 and i != 0:
            print(' ', end='')
        print(cip[i], end='')
    print('\n十六进制密文为')
    cip16 = ''
    dx = 4
    for i in range(16):
        tmp = cip[i * dx:i * dx + dx]
        tmp = int(tmp, 2)
        tmp = hex(tmp)[2:].upper()
        cip16 += tmp
    print(cip16)


if __name__ == '__main__':
    # 读入明文、密钥、加解密设置
    initData()
    # 初始置换生成L0,R0
    initPermutation()
    # 生成子密钥
    get16Key()
    # f函数迭代
    fiter()
    # 打印结果
    printCipher()
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值