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

    1. 题目信息

    题目这样描述:“破解密文,解密msg002.enc文件”,并且提供附件下载,附件中有4个文件:encryptor.c、msg001、msg001.enc与msg002.enc。

    2. 分析

    encryptor.c向我们展示了加密的原理,

    c = (p + (k[i % strlen(k)] ^ t) + i*i) & 0xff;
    

    对明文的每个字符p,按照上述代码生成密文c,之后t更新为p,i增1,再加密下一个字符。只不过,当我写了对应的解密程序进行解密时,得到的明文是乱码。

    我用encryptor.c重新加密了一遍msg001,发现得到的密文与所给的msg001.enc不同,结合加密程序分析,怀疑t的初值或者k被“做了手脚”,我首先穷举了t的256个初值,发现加密的结果均与msg001.enc不同,那么应该是真正加密所用的k并不是encryptor.c展示的k,所以第一步应该解出真正加密所用的k,根据加密原理,k的每一个字符x都能通过下式求出,也就是考察已知明密文求解密钥。

    x=(ord(c)-ord(m)-ii*ii)&0xff
    x^=t
    

    3. 解题

    由密文求明文的程序很简单,难点在于你需要先通过msg001、msg001.enc求解出真正加密所用的密钥。

    def get_true_key(msg_data,cip_data):
        xs=''
        ii,t=0,0
        for m,c in zip(msg_data,cip_data):
            x=(ord(c)-ord(m)-ii*ii)&0xff
            x^=t
            t=ord(m)
            ii+=1
            xs+=chr(x)
        return xs[:(xs[1:].find(xs[0])+1)]
    
    def test(msg_data,cip_data,o_k):
        tt=0
        cip=''
        lk=len(o_k)
        for ii,m in enumerate(msg_data):
            c=(ord(m)+(o_k[ii%lk]^tt)+ii*ii)&0xff
            cip+=chr(c)
            tt=ord(m)
        return all(x==c for x,c in zip(cip,cip_data))
    
    def solve():
        with open('msg001','r') as f:
            msg_data=f.read().strip()
        with open('msg001.enc','r') as f:
            cip_data=f.read().strip()
        with open('msg002.enc','r') as f:
            data=f.read().strip()
        k=get_true_key(msg_data,cip_data)
        print 'the true key is : ',k
        o_k=[ord(c) for c in k]
        assert test(msg_data,cip_data,o_k)
        t=0
        msg=''
        for ii,c in enumerate(data):
            p=(ord(c)-ii*ii-(o_k[ii%28]^t))&0xff
            t=p
            msg+=chr(p)
        with open('msg002','w') as f:
            f.write(msg)
        return msg
    
    if __name__=='__main__':
    #   python solve.py
        print solve().strip()
    

    解出加密所用密钥,破解密文:

    $ python solve.py
    the true key is : VeryLongKeyYouWillNeverGuess
    The known-plaintext attack (KPA) is an attack model for cryptanalysis where the attacker has samples of both the plaintext (called a crib), and its encrypted version (ciphertext). These can be used to reveal further secret information such as secret keys and code books. The term "crib" originated at Bletchley Park, the British World War II decryption operation. 
    The flag is CTF{6d5eba48508efb13dc87220879306619}
    

    简要介绍了已知明文攻击之后,后面给出flag。

  • 相关阅读:
    还是火柴排队(补一下归并排序的锅)
    火柴排队(NOIP2013)(附树状数组专题讲解(其实只是粗略。。。))
    转圈游戏(NOIP2013)
    接口和多态
    HttpClient-传入url得到json字符串( PostMethod method = new PostMethod(url)是个好方法)
    url和资源的再理解
    每天进步一点点- 资源与URI(吐血精华总结)
    每天进步一点点-一切皆对象/一次编写,到处运行/bean工厂
    java黑魔法-反射机制-02-通过Java反射调用其他类方法
    java黑魔法-反射机制-01
  • 原文地址:https://www.cnblogs.com/coming1890/p/13502960.html
Copyright © 2011-2022 走看看