2022-02-09

[第七章 CTF之CRYPTO章]N1DES

# -*- coding: utf-8 -*-
import hashlib,base64
def f(a,b):
    digest = hashlib.sha256(a + b).digest()
    return digest[:8]

def str_xor(a,b):
    return ''.join( chr(ord(a[i]) ^ ord(b[i])) for i in range(len(a)))

def round_add(a, b):
    res = str_xor(f(a,b),f(b,a))
    return res

def permutate(table, block):
    return list(map(lambda x: block[x], table))

def str_permutate(table, block):
    t = map(lambda x: block[x], string_to_list(table))
    return ''.join(chr(i) for i in t)

def string_to_bits(data):
    data = [ord(c) for c in data]
    l = len(data) * 8
    result = [0] * l
    pos = 0
    for ch in data:
        for i in range(0,8):
            result[(pos<<3)+i] = (ch>>i) & 1
        pos += 1
    return result

def string_to_list(data):
    a = []
    a.extend(ord(i) for i in data)
    return a

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

def generate(o):
    k = permutate(o,s_box)
    b = []
    for i in range(0, len(k), 7):
        b.append(k[i:i+7] + [1])
    c = []
    for i in range(32):
        pos = 0
        x = 0
        for j in b[i]:
            x += (j<<pos)
            pos += 1
        c.append((0x10001**x) % (0x7f))
    return permutate(o,s_box)



class N1ES_2:
    def __init__(self, key):
        if len(key) != 32 :
            raise Exception("key must be 32 bytes long")
        self.key = key
        self.gen_subkey()

    def gen_subkey(self):
        o = string_to_bits(self.key)
        k = []
        for i in range(8):
            o = generate(o)
            k.extend(o)
            o = string_to_bits([chr(c) for c in o[0:32]])
        self.Kn = []
        for i in range(32):
            t = map(chr, k[i * 8: i * 8 + 8])
            self.Kn.append(''.join(i for i in t))
        return

    def encrypt(self, plaintext):
        if (len(plaintext) % 16 != 0 or isinstance(plaintext, bytes) == False):
            raise Exception("plaintext must be a multiple of 16 in length")
        res = ''
        for i in range(len(plaintext) / 16):
            block = plaintext[i * 16:(i + 1) * 16]
            L = block[:8]
            R = block[8:]
            for round_cnt in range(32):
                L, R = R, str_xor(round_add(R, self.Kn[round_cnt]),L)
                L, R = str_permutate(L,s_box) , str_permutate(R,s_box)
            L, R = R, L
            res += L + R
        return res


key = "7056b257805ec2b8325795b0e6061f89"
n1es = N1ES_2(key)
cipher = n1es.encrypt(FLAG)
print base64.b64encode(cipher)  # TZPvbvJQ8l2T7G5NmrlDWPLoymq2See29B16+/xf+qk=

读程序可以发现,这就是个很明显的DES
在这里插入图片描述

跟上图不同的是,题目上是循环了32次,本质其实是一样的
DES属于对称密码体制,加密跟解密过程基本一样
题目程序中可以算是将密钥给明了,所以只需要仿照加密程序写出解密程序即可

在N1ES_2中加解密函数

    def decrypt(self, cipher):
        res = ""
        for i in range(len(cipher)//16):
            block = cipher[i * 16:(i+1) * 16]
            L = block[:8]
            R = block[8:]
            L, R = R, L
            for round_cnt in range(32):
                R = map(lambda x: chr(s_box.index(x)), string_to_list(R))
                L = map(lambda x: chr(s_box.index(x)), string_to_list(L))
                L = R
                #str_xor(R, L) = round_add(R现,Kn[31-i])
                R = str_xor(round_add(R, self.Kn[31 - round_cnt]), L)
            res += L + R
        return res

然后就能解密了

理论是不难,但是有个很麻烦的事:python2与python3的兼容性问题
改了好几次还是报错

贴一个官方Wp吧

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

def decrypt(self,cipher):
    res = ''
    for i in range(len(cipher) / 16):
        block = cipher[i * 16:(i + 1) * 16]
        L = block[:8]
        R = block[8:]
        for round_cnt in range(32):
            L, R = str_permutate(L,inv_s) , str_permutate(R,inv_s)
            L, R =  R,str_xor(round_add(R, self.Kn[31 - round_cnt]),L)
        L, R = R, L
        res += L + R
    return res
#n1book{4_3AsY_F3istel_n3tw0rk~~}

[第七章 CTF之CRYPTO章]CommonModulus

公钥密码

from Crypto.Util.number import *

flag = bytes_to_long("n1book{****}")

p = getStrongPrime(1024)
q = getStrongPrime(1024)
n = p * q
e1 = 65537
e2 = 114514191981019

c1 = pow(flag, e1, n)
c2 = pow(flag, e2, n)
print n
print c1
print c2
# 21623080544326498770675136722722081442439962670407342395305257399968527773581643605241107498528119713992996112133936315623505193574782799603552625740778966924901449389879888187296229193572703630895013561444087175709585672299795813307303532524319169791834267438418957827453143225241009361840070934759969916044339329942862741713208492233157686885054848656633606994047037790363445284574522253355820330588355739897608746238421274338160893558077079146666405543198979779203179957475108269486195166116691445583387563226342399303801829616340122550517473370017331840240330038653549495123025292843090770265859170008411116218471
# 3686070958006400066676896030505702217756191695023602240096969503017648828644691192057070046536001572856205835043801785933065850261954210319115823680049891823050292885485323323140033607272590943498691377919095190060985052833112726154274459291873173327659343895562889002010290535716987458497835434051180970393386727569771585825303272194369216597407631372359221306049206080186804424082565150971106654494167453149476990197267600547716764283635086081312961031919543089692705243104365160016279057956490493340808621710104541388922037714689908491034393881273270956513183195581141005108648929958780549505311901183420824202758
# 20519990396147494400829214415220524051576903563262552552508746140570722860446739173237919576359792936423522550105610212640682808724898202791111216569703984637995831736979822035082736739633487200561199241240094912093910049495026489770488782992504677151121715385721047361580850774592966505593868956262508955779543607113010652542097275366794795374310887659456919427340641996939291171422822032239220746577159373621633953025517157564463487003581524575909963352758383177950127910526812843694538203584637074695004394861384092452744111113362733514626260457817063526579839612934117073068466395605475689722150376414880287178988

这就很熟悉了,共模攻击

_, r, s = gmpy2.gcdext(e1, e2)

m = pow(c1, r, n) * pow(c2, s, n) % n
print(long_to_bytes(m))

运行得到:n1book{c0mm0n_m0du1u5_4ttacK}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值