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。

  • 相关阅读:
    C嵌入汇编
    App 运营 推广相关
    POJ 3904 Sky Code
    数组的复制与动态扩展算法
    另类病毒的自删除方法
    oracle触发器中增删改查本表
    POJ 2773 Happy 2006 数学题
    Android手机便携式wifi的使用及无线数据传输(主要针对XP系统)
    Find the minimum线段树成段更新
    使用visual c++ 2005编译64位可执行文件
  • 原文地址:https://www.cnblogs.com/coming1890/p/13502960.html
Copyright © 2011-2022 走看看