注:我将承担加密和解密运算都做模256
既然你加密和解密具有两个8位密钥的单个字节,该密码的密钥空间比消息空间大256倍。这意味着对于每个(A,E)
对,存在K
和K2
的256种可能组合。
具体地,如果A = (E - (KEY^KEY2))^KEY
,然后KEY2 = (E - (A^KEY))^KEY
。使用此公式对于给定的一对(A,E)
,可以很容易地通过的KEY
所有256个值进行迭代,将获得的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)
编辑:下面的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);
只是为了帮助你搜索的未来,你正在试图做的事情被称为“已知的明文攻击“ –
您没有提供足够的数据来重建密钥和key2。 (0x07,0x14),(0x17,0x14),(0x47,0x14),(0x57,0x14),(0x67,0x54),(0x77,0x54)'是现在可能的答案。 –
我可以给更多的数据来重建键和键2,怎么我已经解密和加密的文件,我只是比较他们得到值对,但现在我只是希望有人帮助我获得钥匙和密钥key2算法或伪 – navirius