2017-01-27 32 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您正确的怀疑:-) –