我正在研究 Double-DES 上的中间相遇攻击。我已经实现了 DES 加密/解密并完成了加密,现在我想对 Double-DES 执行 MITM 攻击以找到密钥。我尝试实现此目的的方法是在 for 循环中将中间密码存储为 HashMap 的键,并将可能的键存储为 HashMap 的值。然而,在这个 for 循环中,我还想确保可能的键是唯一的,即我有一个 if 语句,它检查可能的键是否已存在于 HashMap 中。如果没有,则使用它来加密明文并将密文和可能的密钥存储在 HashMap 中。之后,我尝试通过使用 foreach 迭代 HashMap 来找到具有匹配中间密文的密钥,并将加密中的每个中间密文与解密中的中间密文进行比较。
但是,我无法找到比赛,因为完成时间太长。我已经等了大约2个小时了,没有任何结果。如果我删除 if 语句,它会检查可能的键是否已在 HashMap 中,它会在大约 10 秒内完成。
for (int size = intermediateCipher.size(); size < Math.pow(2, 20); size++) { // intermediateCipher is my HashMap consisting of <String, byte[]>
byte[] possibleKey = generateDesKey(); // generateDesKey generates a key of 64 bits
if (!intermediateCipher.containsValue(possibleKey)) {
intermediateCipher.put((encrypt(possibleKey, plainText)).toString(), possibleKey);
}
}
int count = 0;
for (Entry<String, byte[]> arr : intermediateCipher.entrySet()) {
String temp = (decrypt(arr.getValue(), cipherText)).toString();
if (intermediateCipher.containsKey(temp)) {
count++;
}
}
值得一提的是,只有 20 位的 DES 密钥是有效的。这就是为什么有 2^20 个可能的键。此外,如果我没有 if 语句来检查可能的键是否已在 HashMap 中,我会得到 510 个匹配项,这太多了。
UPDATE:
我尝试使用 Set 来首先存储密钥,然后使用 Set 中的密钥进行加密等。但是,我尝试使用 while 循环,而不是使用从 0 到 2^20 迭代的 for,只要 Set 有元素,它就会检查迭代。然而,我已经尝试运行此方法超过 10 分钟,但没有任何结果。它永远不会脱离循环。
for (int i = 0; i < Math.pow(2, 20); i++) {
possibleKeySet.add(generateDesKey());
}
System.out.println(possibleKeySet.size());
for (int i = 0; i < possibleKeySet.size(); i++) {
intermediateCipher.put((encrypt(possibleKeySet.iterator().next(), plainText)).toString(),
possibleKeySet.iterator().next());
}
System.out.println("ss " + intermediateCipher.size());
int count = 0;
for (Entry<String, byte[]> arr : intermediateCipher.entrySet()) {
String temp = ((decrypt(arr.getValue(), cipherText)).toString());
if (intermediateCipher.containsKey(temp)) {
count++;
}
}
我读过,对于一个集合,hasNext() 对于非空集合总是返回 true。因此,我尝试过使用每个键,但是 hashMap 的大小永远不会与键集的大小相同,这对我来说没有意义,因为我使用了键集中的每个键:
for (int i = 0; i < Math.pow(2, 20); i++) {
possibleKeySet.add(generateDesKey());
}
System.out.println(possibleKeySet.size());
for (byte[] key : possibleKeySet) {
intermediateCipher.put((encrypt(key, plainText)).toString(),
key);
}