【问题标题】:Reverse known XOR encryption algorithm反向已知异或加密算法
【发布时间】:2017-01-27 06:26:32
【问题描述】:

我有 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

谢谢

【问题讨论】:

  • 只是为了帮助您将来进行搜索,您尝试做的事情称为“已知明文攻击”
  • 您没有提供足够的数据来重建 key 和 key2。 (0x07, 0x14), (0x17, 0x14), (0x47, 0x14), (0x57, 0x14), (0x67, 0x54), (0x77, 0x54) 现在是可能的答案。
  • 我可以提供更多数据来重建密钥和密钥2,因为我已经解密和加密文件,我只是比较它们以获得值对,但现在我只想有人帮我获取密钥和密钥2算法或伪代码

标签: c# algorithm encryption cryptography xor


【解决方案1】:

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

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

具体来说,如果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)

编辑:以下 C# 代码由 Eric Lippert 建议:

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);

【讨论】:

  • 您认为这在 Python 中比 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);
  • 我怀疑在 Python 中更容易,因为您了解 Python。我想起了一位法国哲学家,他认为法语是最好的语言,因为它是唯一的语言,其中单词的顺序与您认为它们的顺序相同。
  • @squeamishossifrage 你能给我一个布尔运算的链接吗,比如你的最终方程 KEY2 = (E - (A ^ KEY)) ^ KEY,我仍然很困惑如何一步一步得到这个公式
  • @navirius:用代数解决。给你方程E = (A ^ KEY) + (KEY ^ KEY2) 并要求求解KEY2。首先从两边减去:E - (A^K) = K^K2 现在你怎么能从右边消除 K? 提示:你知道哪些身份涉及 xor 操作?
猜你喜欢
  • 2021-05-16
  • 2012-01-27
  • 2011-10-18
  • 2013-03-29
  • 1970-01-01
  • 2021-12-06
  • 2013-04-04
  • 2019-08-08
  • 1970-01-01
相关资源
最近更新 更多