• 攻防世界-密码学-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。

  • 相关阅读:
    IntelliJ IDEA使用心得之问题篇;
    IntelliJ IDEA使用心得之Maven项目篇
    IntelliJ IDEA使用心得之非Maven项目篇
    IntelliJ IDEA使用心得之插件篇
    IntelliJ IDEA使用心得之快捷键篇
    新博客地址
    【转载】Dijkstra算法和Floyd算法的正确性证明
    【转载】最小生成树之Kruskal算法
    论自动AC机
    【转载】C++ STL priority_queue用法
  • 原文地址:https://www.cnblogs.com/coming1890/p/13502960.html
Copyright © 2020-2023  润新知