反向已知的XOR加密算法

时间:2017-01-27 06:26:32

标签: c# algorithm encryption cryptography 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,它应具有解密值0x49

请注意 我尝试恢复我的KEY和KEY2以获取遗失的音符

谢谢

1 个答案:

答案 0 :(得分:2)

  

注意:我将假设加密和解密算法都以模256完成。

由于您使用两个8位密钥加密和解密单个字节,因此该密码的密钥空间比消息空间大256倍。这意味着每KK2(A,E)有256种可能的组合。

具体而言,如果是A = (E - (KEY ^ KEY2)) ^ KEY,那么KEY2 = (E - (A ^ KEY)) ^ KEY。对给定的(A,E)对使用此公式,您可以轻松遍历KEY的所有256个值并获得相应的KEY2值。对每对明文/密文字符重复此过程,并计算所有(KEY,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)

编辑: Eric Lippert建议使用以下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);