Java bruteforce for循环,结果令人困惑

时间:2016-06-02 17:57:13

标签: java for-loop aes cbc-mode

我创建了一个小程序,试图从AES-CBC密钥中找到20个丢失的位。结构如下:

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Ex02 {
    private static final byte[] firstPart = {0x43, 0x72, 0x1a, 0x5b,
            (byte) 0x8e, (byte) 0xde, 0x5f, 0x57,
            (byte) 0x89, (byte) 0xf0, (byte) 0xdd, 0x28,
            0x68, (byte) 0x80};
    private static final byte[] SOLUTION = {0x43, 0x72, 0x1a, 0x5b,
            (byte) 0x8e, (byte) 0xde, 0x5f, 0x57,
            (byte) 0x89, (byte) 0xf0, (byte) 0xdd, 0x28,
            0x68, (byte) 0x8d, 0x63, (byte) 0xc5};
    private static final byte[] IV = {(byte) 0x80, (byte) 0x81, (byte) 0x82, (byte) 0x83,
            (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87,
            (byte) 0x88, (byte) 0x89, (byte) 0x8a, (byte) 0x8b,
            (byte) 0x8c, (byte) 0x8d, (byte) 0x8e, (byte) 0x8f};
    private static byte[] currentKey = new byte[IV.length];
    private static final byte[] chiffrat = Chiffrat.getAsHex();

    // For debugging purposes, this is set as class-variable
    private static int i;

    public static void main(String[] args) {
        Cipher c;

        // 20 Bits are missing, so 20 Bits to test
        int rounds = (int) Math.pow(2, 20);
        try {
            c = Cipher.getInstance("AES/CBC/NoPadding");

            // Test every possible key
            for (i = 0xd63c3; i < rounds; i++) {
                // For tracking progress
                if (i%100000==0 && i > 1) System.out.println(i + "/" + rounds);

                // Create Key out of first and second part
                // First convert i to a six digit hex number
                String tmp = Integer.toHexString(i);
                while (tmp.length() < 6) {
                    tmp = "0" + tmp;
                }

                // Convert String into byte array
                byte[] secondPart = new byte[tmp.length() / 2];
                for (int j = 0; j < tmp.length(); j+=2) {
                    secondPart[j / 2] = (byte) Integer.parseInt(tmp.substring(j, j + 2), 16);
                }

                // Copy first key part into the final key array
                System.arraycopy(firstPart, 0, currentKey, 0, firstPart.length);

                // Attach second part to the final key
                for (int j = 0; j < secondPart.length; j++) {
                    currentKey[currentKey.length - secondPart.length + j] |= secondPart[j];
                }

                // Decrypt
                SecretKeySpec secretKeySpec = new SecretKeySpec(currentKey, "AES");
                c.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(IV));
                byte[] result = c.doFinal(chiffrat);

                // Check if decrypted text is useful
                if (checkEnglish(result)) {
                    System.out.println("Key found!");
                    System.out.println("Counter: " + i);
                    System.out.println("Generated String: " + tmp);
                    System.out.println("First Part: 0x" + byteArrayToString(firstPart));
                    System.out.println("Second Part: 0x" + byteArrayToString(secondPart));
                    System.out.println("Used Key: 0x" + byteArrayToString(currentKey));
                    System.out.println("Result: " + new String(result));
                    break;
                }
            }
        } catch (Exception e) {
            System.out.print("ERROR: ");
            e.printStackTrace();
        }
    }

    private static boolean checkEnglish(byte[] b) {
        String tmp = new String(b).toLowerCase();
        return (tmp.contains("the") && tmp.contains("to") && tmp.contains("in") && tmp.contains("and"));
    }

    private static String byteArrayToString(byte[] bArr) {
        String result = "";
        for (byte b : bArr) {
            result += Integer.toHexString(Byte.toUnsignedInt(b));
        }
        return result;
    }
}

所以这就是问题所在: 如果我从0开始,我得不到任何结果。用于跟踪目的的字符串始终打印,直到我达到2 ^ 20。但是,如果我将i设置为所需的解决方案0xd63c5或0xd63c4,我将获得解密的文本。即使使用0xd63c3,也没有&#34;功能&#34;。 也许我看不到树木的木材,但我现在尝试找到一种解决方案。

任何帮助表示感谢,提前谢谢。

1 个答案:

答案 0 :(得分:0)

正如JF Meier所说,将byte[] currentKey更改为局部变量并在for循环中初始化它可以解决问题。
由于currentKey在循环时没有重新初始化,因此每个可能的键都是OR-concatenated i1 | i2 | ... | in,并且永远不会达到所需的值(0xd63c5)。