我有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以获取遗失的音符
谢谢
答案 0 :(得分:2)
注意:我将假设加密和解密算法都以模256完成。
由于您使用两个8位密钥加密和解密单个字节,因此该密码的密钥空间比消息空间大256倍。这意味着每K
对K2
和(A,E)
有256种可能的组合。
具体而言,如果是A = (E - (KEY ^ KEY2)) ^ KEY
,那么KEY2 = (E - (A ^ KEY)) ^ KEY
。对给定的(A,E)
对使用此公式,您可以轻松遍历KEY
的所有256个值并获得相应的KEY2
值。对每对明文/密文字符重复此过程,并计算所有(KEY,KEY2)
对结果集的交集。在明文和密文中有足够数量的字符,这应该会给你一个独特的结果。
我知道您将此问题标记为c#,但在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);