注:我將承擔加密和解密運算都做模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