zoukankan      html  css  js  c++  java
  • 攻防世界-密码学-SM

    1. 题目信息

    附件中包含一个Python脚本sm.py,3个文本文件。

    2. 分析

    读完一遍sm.py后,可以确定解题的思路是先由ps与r解出bchoose,再由bchoose按照同样的过程计算出密钥key,最后进行AES解密求出flag。首先看生成r的代码:

    r=0
    for i in range(512):
        if bchoose[i]=='1':
            r=r^ps[i]
    

    (r=sum_{i=1}^{512} extrm{bchoose[i]}cdot extrm{ps[i]})(此处的加法是异或);虽然生成方式类似背包加密,但是由于ps具有很好的性质,我们不使用破解背包加密的方法来解此题;我们来分析生成ps的gen512num函数:

    def gen512num():
        order=[]
        while len(order)!=512:
            tmp=randint(1,512)
            if tmp not in order:
                order.append(tmp)
        ps=[]
        for i in range(512):
            p=getPrime(512-order[i]+10)
            pre=bin(p)[2:][0:(512-order[i])]+"1"
            ps.append(int(pre+"0"*(512-len(pre)),2))
        return ps
    

    order是1,2,...,512的一个随机的排列,对ps[i]:首先生成一个长度为512-order[i]+10的素数,去掉此素数的最后10位,同时在尾部追加一个二进制位1,最后在后面填充0使得长度为512;我们首先考虑生成r的最后1个二进制位,ps中只有1个数最后1位为1,其余数最后1位均为0,那么最后1位为1的数如果没有“加入”异或运算,那么r的最后1位一定为0,否则,一定为1,这样我们通过r的最后1位就可以推断出bchoose的第j位(记order[j]=1)。接下来,(roplus ( extrm{bchoose[j]}cdot extrm{ps[j]})=sum_{i eq j} extrm{bchoose[i]}cdot extrm{ps[i]}),在{ps[i]| i( eq)j}中,只有1个数倒数第2位为1,同理,可推断出bchoose的第k位(记order[k]=2),直到推断出bchoose所有位。

    3. 解题

    实现的Python脚本如下:

    from base64 import b64decode
    from hashlib import md5
    from Crypto.Cipher import AES
    from Crypto.Util.number import long_to_bytes
    
    def cal_k():
        with open('ps','r') as f:
            ps=[long(x) for x in f.read().split('
    ')[:-1]]
        with open('r','r') as f:
            r=long(f.read())
        pbits=[bin(x).rfind('1')-2 for x in ps]
        bc=['0']*512
        for le in range(512):
            ind=pbits.index(511-le)
            tt=bin(r)[2:].rjust(512,'0')[511-le]
            if tt=='1':
                bc[ind]='1'
                r^=ps[ind]
        return long(''.join(bc),2)
    
    def solve():
        with open('ef','rb') as f:
            ef=b64decode(f.read())
        key=long_to_bytes(int(md5(long_to_bytes(cal_k())).hexdigest(),16))
        aes_obj = AES.new(key, AES.MODE_ECB)
        return aes_obj.decrypt(ef)
    
    if __name__=='__main__':
        print solve()
    

    程序运行结果如下:

    $ python solve.py
    flag{shemir_alotof_in_wctf_fun!}
    
  • 相关阅读:
    C# 单点登录
    长度12的数组,要求对数据分为3组,每组数据对应位置的数字为前几位的和,并返回12位数组
    react项目初始化
    vue 过滤器的使用(解决forEach遇到的问题)
    nuxt中less使用
    vue项目less 使用
    Webpack中的sourceMap配置
    webpack 同一文件打包两次生成两个文件
    webpack---图片打包前和打包后名称一致的配置
    The computed property "userName" is already defined in data.
  • 原文地址:https://www.cnblogs.com/coming1890/p/13547193.html
Copyright © 2011-2022 走看看