DES密码-py脚本

DES密码-py脚本

原理脚本

# -*- coding: utf-8 -*-
# @Time : 2020-12-09 8:24
# @File : DES密码.py
# @Author : mirror
# @Software: PyCharm


import re
import base64

IP_table = [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_re_table = [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]

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]

S = [
    [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],

    [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],

    [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],

    [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],

    [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],

    [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],

    [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],

    [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],

]

# key
PC_1tab = [57, 49, 41, 33, 25, 17, 9,  # 选择置换1表
           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]

PC_2tab = [14, 17, 11, 24, 1, 5,  # 选择置换2表
           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]

# 将明文转化为二进制
def str2bin(message):
    res = ''
    for i in message:
        tmp = bin(ord(i))[2:]  # 将每个字符转化成二进制
        tmp = str('0' * (8 - len(tmp))) + tmp  # 补齐8位
        res += tmp
    if len(res) % 64 != 0:
        count = 64 - len(res) % 64  # 不够64位补充0
    else:
        count = 0
    res += '0' * count
    return res


# 将密钥转化为二进制,全部秘钥以补0的方式实现长度不满足64位的情况
def key2bin(key):
    res = ''
    for i in key:
        tmp = bin(ord(i))[2:]  # 将每个字符转化成二进制
        tmp = str('0' * (8 - len(tmp))) + tmp  # 补齐8位
        res += tmp
    if len(res) < 64:
        count = 64 - len(res) % 64  # 不够64位补充0
        res += '0' * count
    else:
        res = res[:64]
    return res

# IP盒处理
def ip_change(str_bin):
    res = ''
    for i in IP_table:
        res += str_bin[i - 1]
    return res

#置换函数
def zhihuan(s, tab):  # 通过置换表置换
    strlen = len(tab)
    list1 = []
    for i in range(0, strlen):
        j = tab[i]
        list1.extend(str(s[j - 1]))
    s1 = "".join(list1)
    return s1

#密钥循环左移
def zuoyi(s, n):  # s循环左移n位
    strlen = len(s)
    n = n % strlen
    list1 = list(s)
    for i in range(0, strlen):
        if i < n:
            list1.extend(list1[0])
            del list1[0]
        else:
            break
    s1 = "".join(list1)
    return s1

#求子密钥
def gen_key(key) :
    Kkid = []  # 子密钥存放列表
    Kzhihuan1 = zhihuan(key, PC_1tab)  # 置换选择1
    C = Kzhihuan1[0:28]
    D = Kzhihuan1[28:56]
    for Kkidi in range(0, 16):
        C = zuoyi(C, SHIFT[Kkidi])  # 左移对应的位数
        D = zuoyi(D, SHIFT[Kkidi])
        Kkid.append(zhihuan(C + D, PC_2tab))  # 置换选择2
    return Kkid

# E盒置换
def e_change(str_left):
    res = ""
    for i in E:
        res += str_left[i - 1]
    return res

#异或运算
def xor_change(str1, str2):
    res = ""
    for i in range(0, len(str1)):
        xor_res = int(str1[i], 10) ^ int(str2[i], 10)  # 进行xor操作
        if xor_res == 1:
            res += '1'
        if xor_res == 0:
            res += '0'
    return res

#S盒置换
def s_change(my_str):
    res = ""
    c = 0
    for i in range(0, len(my_str), 6):  # 步长为6   表示分6为一组
        now_str = my_str[i:i + 6]  # 第i个分组
        row = int(now_str[0] + now_str[5], 2)  # 第r行
        col = int(now_str[1:5], 2)  # 第c列
        # 第几个s盒的第row*16+col个位置的元素
        num = bin(S[c][row * 16 + col])[2:]  # 利用了bin输出有可能不是4位str类型的值,所以才有下面的循环并且加上字符0
        for gz in range(0, 4 - len(num)):  # 补全4位
            num = '0' + num
        res += num
        c += 1
    return res

#P置换
def p_change(bin_str):
    res = ""
    for i in P:
        res += bin_str[i - 1]
    return res

 # E扩展置换
def f(str_left, key):
    e_change_output = e_change(str_left)
    xor_output = xor_change(e_change_output, key)  # 将48位结果与子密钥Ki进行异或(xor)
    s_change_output = s_change(xor_output)
    res = p_change(s_change_output)
    return res


# IP逆盒处理
def ip_re_change(bin_str):
    res = ""
    for i in IP_re_table:
        res += bin_str[i - 1]
    return res

#主要加密函数
def encrypt():
    bin_str = str2bin(input('请输入明文:'))
    bin_key = key2bin(input('请输入密钥:'))
    print('------------16个子密钥------------')
    tmp = re.findall(r'.{64}', bin_str)  #每64位一组
    a = gen_key(bin_key)
    re_L = []
    re_R = []
    for i in range(16) :
    	print("k" + str(i + 1) + "=" + a[i])
    print('------------左半部分------------')
    result = ''
    for i in tmp:
        str_bin = ip_change(i)  # IP置换
        key_lst = gen_key(bin_key)  # 生成16个子密钥
        str_left = str_bin[:32]
        str_right = str_bin[32:]
        for j in range(15):  # 先循环15次 因为最后一次不需要不用换位
            f_res = f(str_right, key_lst[j])
            str_left = xor_change(f_res, str_left)
            str_left, str_right = str_right, str_left
            re_L.append(str_left)
            re_R.append(str_right)
        f_res = f(str_right, key_lst[15])  # 第16次
        str_left = xor_change(str_left, f_res)
        fin_str = ip_re_change(str_left + str_right)  # ip的逆
        result += fin_str
    last = hex(int(result,2))[2:]        #十六进制输出密文
    for q in range(len(re_L)) :
        print('L' + str(q+1) + '=' + re_L[q])
    print('L16=' + re_R[14])
    print('------------右半部分------------')
    for p in range(len(re_R)) :
        print('R' + str(p+1) + '=' + re_R[p])
    print('R16=' + str_left)
    print('------------密文------------')
    #print('\n十六进制密文为:', last)
    print("\nbase64密文为 :" + str(base64.b64encode(last.encode('utf-8')))[2:-1])


if __name__ == '__main__':
    encrypt()

在这里插入图片描述

pyDES库写的

# -*- coding: utf-8 -*-
# @Time : 2020-12-17 19:50
# @File : pydes.py
# @Author : mirror
# @Software: PyCharm

from binascii import *
from pyDes import *
import base64

data = "this is a test!"
key = "testtest"
vi = key
padmode = PAD_PKCS5
encrypt = des(key,CBC,IV=vi,padmode=padmode)
en_data = encrypt.encrypt(data)
en_data = base64.b64encode(b2a_hex(en_data))
print(u"base64密文:" , str(en_data,encoding='utf-8'))
da_data = base64.b64decode(en_data)
da_data = encrypt.decrypt(a2b_hex(da_data))
print(u"解密的明文 :", str(da_data,encoding='utf-8'))


ncrypt = des(key,CBC,IV=vi,padmode=padmode)
en_data = encrypt.encrypt(data)
en_data = base64.b64encode(b2a_hex(en_data))
print(u"base64密文:" , str(en_data,encoding='utf-8'))
da_data = base64.b64decode(en_data)
da_data = encrypt.decrypt(a2b_hex(da_data))
print(u"解密的明文 :", str(da_data,encoding='utf-8'))

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值