1. 程式人生 > 實用技巧 >攻防世界-密碼學-Easy one

攻防世界-密碼學-Easy one

1. 題目資訊

題目這樣描述:“破解密文,解密msg002.enc檔案”,並且提供附件下載,附件中有4個檔案:encryptor.c、msg001、msg001.enc與msg002.enc。

1. 分析

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=''
    for ii,m in enumerate(msg_data):
        c=(ord(m)+(o_k[ii%28]^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()
    with open('msg001.enc','r') as f:
        cip_data=f.read()
    with open('msg002.enc','r') as f:
        data=f.read()
    k=get_true_key(msg_data,cip_data)
    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()

解出加密所用金鑰,破解密文:

$ 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。