[冀信2021-crypto] ez-crypto

昨晚上终于作出来了,回头一想也不难。把思路整理清楚了就好办了。

传附后也麻烦,直接上原题吧

import random
import os
from Crypto.Cipher import DES
from Crypto.Util.number import *

def encode(m,k):
        s=[]
        for i in m:
                s.append(sbox[i])
        s=s[3:]+s[0:3]
        assert len(s)==len(k)
        r = []
        for i in range(len(m)):
                r.append(s[i]^k[i])
        return r

def encrypto(m,k):
        y = encode(m,k)
        y = encode(y,k)
        return y

sbox=list(range(256))
random.shuffle(sbox)

print(sbox)
key=os.urandom(8)
secret=[1,2,3,4,5,6,7,8]
r = encrypto(secret,key)
print(r)

secret=os.urandom(8)
r = encrypto(secret,key)
print(r)
d=DES.new(secret,DES.MODE_ECB)
flag=b"DASCTF{*}"
print(d.encrypt(flag).hex())

'''
[53, 215, 0, 67, 172, 88, 48, 103, 188, 205, 12, 249, 204, 146, 66, 189, 165, 71, 124, 197, 134, 44, 30, 191, 106, 243, 64, 152, 113, 40, 184, 163, 176, 180, 175, 168, 105, 229, 220, 150, 238, 181, 52, 51, 61, 65, 56, 62, 136, 92, 164, 158, 99, 209, 166, 244, 125, 195, 57, 224, 8, 154, 20, 241, 126, 1, 83, 202, 72, 148, 171, 45, 4, 34, 69, 70, 248, 161, 59, 68, 107, 60, 253, 81, 225, 26, 42, 31, 22, 157, 206, 19, 76, 196, 117, 246, 120, 222, 16, 39, 122, 41, 162, 24, 192, 95, 233, 177, 10, 77, 85, 247, 130, 109, 245, 211, 21, 237, 82, 252, 58, 221, 135, 28, 93, 207, 242, 174, 111, 138, 153, 208, 32, 214, 80, 129, 194, 179, 6, 144, 199, 55, 160, 141, 73, 110, 218, 5, 35, 186, 15, 132, 149, 96, 29, 74, 156, 143, 54, 131, 167, 116, 25, 23, 147, 47, 94, 203, 7, 178, 102, 75, 250, 173, 9, 213, 200, 231, 89, 254, 49, 97, 43, 217, 239, 155, 127, 219, 90, 112, 101, 223, 128, 234, 159, 193, 37, 236, 232, 170, 86, 11, 46, 121, 133, 63, 118, 228, 91, 198, 27, 3, 201, 119, 255, 36, 212, 251, 50, 2, 104, 33, 235, 140, 14, 84, 98, 151, 226, 240, 137, 114, 78, 13, 185, 18, 123, 190, 79, 216, 183, 139, 210, 182, 87, 115, 100, 187, 17, 230, 142, 108, 169, 38, 227, 145]
[149, 52, 49, 137, 136, 226, 194, 207]
[50, 151, 237, 63, 223, 12, 118, 138]
4cc917e07ec87f5a481843e3a21ef0f1178bb3b5712b25637359bb9e66b684af5f922520066f9e8b
'''

加密过程:

  • 先生成个码表 已知
  • 先用书知的secret和随机的key加密得到r1 已知
  • 再用key和随机的secret加密得到r2 已知
  • 再通过secret进行des加密得到密文

加密函数:

  • 将secret查码表得到m
  • m向前循环移3位
  • 对应的m与key异或得到y
  • 重复第2次

看下第一步的具体过程:

  • 以secret[0]为例,先查码表得到 m[0]=sbox[secret[0]]
  • 再进行一次移位 m[5] = m[0]
  • 再与对应的key进行异或 y[5]=m[5]^key[5]
  • 因为加密是进行两次,所以接下来用y[5]作为secret再进行一次
  • m[5] = sbox[y[5]]
  • m[2] = m[5]
  • y[2] = m[2]^key[2] 这时y[2]已经给出

secret[0]先后与key[5],key[2]运算得到r1[2]所以一次并不能得到对应的key,但可以得到key[2],key[5]的对由于是异或运算,这种对有256组

第一步的解密过程:

  • 先求出8组对应的key对
  • 然后从0开始找链,也就是说假设key[0]正确,找到对应的key[3],再根据key[3]找到key[6],最后找到key[0] 这个key[0]如果跟一开始假设的key[0]是同一个则说明暴出的key是正确的
sbox = [...原题上有...]
r1 = [149, 52, 49, 137, 136, 226, 194, 207]
secret=[1,2,3,4,5,6,7,8]
#找到key对存入tk
tk = []
for k in range(8):
    ttk = []
    for i in range(256):  #0
        for j in range(256):  #5
            v1 = (k+3)%8
            s0 = sbox[secret[v1]] ^ i
            s1 = sbox[s0] ^j 
            if s1 == r1[(k+5)%8]:
                #print('0,',i,',5,',j ) 
                ttk.append(j) 
    tk.append(ttk)
#key对的顺序
srd = [0,5,2,7,4,1,6,3]
key   =[0,0,0,0,0,0,0,0]
for v in range(1):
    srd = srd[1:]+srd[:1]
    for i in range(256):
        tmp = i 
        for j in srd:
            tmp = tk[j][tmp]
        if tmp == i:
            t = i 
            print(t)
            t2 = t 
            tmpkey = [0,0,0,0,0,0,0,0]
            for t1 in srd:
                print(t2,end=',')
                tmpkey[t1]=t2
                t2 = tk[t1][t2]
            print("")
            print(tmpkey)            
            print(encrypto(secret,tmpkey)) 

#key = [72, 133, 21, 30, 215, 0, 227, 42]

第二步的加密过程:

  • 第二步是key已知(上一步已得到)然后求secret
  • 同样是第一步的过程secret[0]查表得到 m[5] = m[0]=sbox[secret[0]]
  • y[5] = m[5]^key[5]
  • m[2]=m[5]=sbox[y[5]]
  • y[2] = m[2]^key[2] == r2[2]
  • 但这里key是已知的,所以可以直接逆向求到secret

第二步的解密过程:

  • 按相反顺序先将r2[0]^key[0]
  • 然后反查码表再移位改为3
  • 再用y[3]^key[3]得到secret[6]
r2 = [50, 151, 237, 63, 223, 12, 118, 138]
secret = [0,0,0,0,0,0,0,0]
for i in range(8):
    secret[(i+6)%8] = sbox.index(sbox.index(r2[i]^key[i]) ^ key[(i+3)%8])

print(secret)
print(encrypto(secret,key)) 
#secret = [92, 47, 88, 14, 154, 185, 100, 81]

第二步处理完后,下边就是已知密钥的情况下des解密

d=DES.new(bytes(secret),DES.MODE_ECB)
print(d.decrypt(bytes.fromhex('4cc917e07ec87f5a481843e3a21ef0f1178bb3b5712b25637359bb9e66b684af5f922520066f9e8b')))

#DASCTF{a242ef7a9aa9f4416fa2b0401558b846}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值