2017-01-27 58 views
2

我XOR加密和解密算法,和它的工作,這樣的代碼反向稱爲XOR加密算法

int Encryption(int A) 
    { 
     E = (A^KEY) + (KEY^KEY2); 
     return E; 
    } 
    int Decryption(int E) 
    { 
     A = (E - (KEY^KEY2))^KEY; 
     return A; 
    } 

我的問題是,如何讓KEY和KEY2如果我知道加密值和解密值 例: 加密值0x53它應該有解密值0X47 加密值0x5E它應該有解密值0x4C 加密值0x61它應該有解密值×49

注 我嘗試恢復我的鑰匙和KEY2尋找我丟失的音符

感謝

+3

只是爲了幫助你搜索的未來,你正在試圖做的事情被稱爲「已知的明文攻擊「 –

+0

您沒有提供足夠的數據來重建密鑰和key2。 (0x07,0x14),(0x17,0x14),(0x47,0x14),(0x57,0x14),(0x67,0x54),(0x77,0x54)'是現在可能的答案。 –

+0

我可以給更多的數據來重建鍵和鍵2,怎麼我已經解密和加密的文件,我只是比較他們得到值對,但現在我只是希望有人幫助我獲得鑰匙和密鑰key2算法或僞 – navirius

回答

2

注:我將承擔加密和解密運算都做模256

既然你加密和解密具有兩個8位密鑰的單個字節,該密碼的密鑰空間比消息空間大256倍。這意味着對於每個(A,E)對,存在KK2的256種可能組合。

具體地,如果A = (E - (KEY^KEY2))^KEY,然後KEY2 = (E - (A^KEY))^KEY。使用此公式對於給定的一對(A,E),可以很容易地通過的KEY所有256個值進行迭代,將獲得的KEY2對應的值。對每對明文/密文字符重複此過程,並計算所有結果集對的交集。在明文和密文中有足夠多的字符時,應該給你一個獨特的結果。

我知道你標記這個問題爲,但它更容易做這樣的事情在Python。下面的代碼可能效率不高,但這並不重要,因爲我們只在這裏處理玩具密碼。

def retrieve_keys(plain,cipher): 
    # Initialize set with all 65536 possible key pairs 
    key_pairs = set([(x,y) for x in range(256) for y in range(256)]) 
    # Intersect this set with the set of 256 possible key pairs for 
    # each plaintext/ciphertext pair 
    for i in range(len(plain)): 
     a, e = ord(plain[i]), ord(cipher[i]) 
     s = set([]) 
     # if a = (e - (key^key2))^key, then key2 = (e - (a^key))^key 
     for key in range(256): 
      s.add((key, ((e - (a^key)) % 256)^key)) 
     key_pairs = key_pairs.intersection(s) 
    # Print out the remaining set of possible key pairs 
    for kp in key_pairs: 
     print "KEY=%d, KEY2=%d" % kp 

# Example (should output "KEY=117, KEY2=80" and "KEY=245, KEY2=80"): 
plaintext = "Hello world, this is a test" 
ciphertext = "b5>>?z'?,>6~z&BA+zA+z9z&5+&" 
retrieve_keys(plaintext,ciphertext) 

編輯:下面的C#代碼建議由埃裏克利珀:

foreach (var kp in 
    Enumerable.Range(0, plain.Length).Aggregate(
    (from x in Enumerable.Range(0, 256) 
     from y in Enumerable.Range(0, 256) 
     select new { x, y }).ToList(), 
    (pairs, i) => pairs.Intersect(
     from x in Enumerable.Range(0, 256) 
     select new { x, y = 
     ((cipher[i] - (plain[i]^x)) % 256)^x }).ToList())) 
    Console.WriteLine(kp); 
+1

你的想法,這在Python中非常簡單,比C#很奇怪。在這裏,讓我把你的解決方案放進這個評論中,並注入一百個字符:'foreach(Enumerable.Range中的var kp(0,plain.Length).Aggregate((從Enumerable.Range中的x(0,256)在Enumerable.Range(0,256)選擇新的{X,Y})。ToList(),\t(對,I)=> pairs.Intersect(從X在Enumerable.Range(0,256)選擇新的{X, Y =((密碼[Ⅰ] - (純[I]^X))%256)^ X})ToList()))\t Console.WriteLine(KP);' –

+0

我懷疑它是在Python更容易,因爲。你知道Python。我想起這位法國哲學家,他認定法語是最好的語言,因爲它是唯一一種語言,其語言與您認爲的語言相同*。 –

+0

@EricLippert您正確的懷疑:-) –