Ошибка: данный последний блок заполнен неправильно

Я получаю ошибку каждый раз, когда я запускаю это

"Ошибка: данный последний блок заполнен неправильно"

В основном я пытаюсь перебрать последние 3 байта ключа, первые 13 байтов верны. Есть идеи, что я делаю не так? Я попытался удалить отступы, и это работает, но он не смог найти открытый текст, который, я уверен, существует и содержит слово "Мария имела". Примечание: я использую sun.misc.BASE64Decoder

вот часть моего кода.

        String myiv = new String(new byte[] {
                0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x31,0x30,0x31,0x31,0x31,0x32,0x33
        });

        char [] mykeyarray = new char[] {0x86,0xe5,0x30,0x90,0xff,0x62,0xa0,0x9a,0x81,0x00,0xad,0x9e,0x8f,0x00,0x00,0x00};
        String encoded = "dm8cfvs+c7pKM+WR+fde8b06SB+lqWLS4sZW+PfQSKtTfgPknzYzpTVOtJP3JBoU2Uo/7XWopjoPDOlPr24duuck0z+vAx91bYTwQo4INnIIBkj/lhJMWmvAKaUIO3qzBoGg8ynQOhuG6LY7Wo0uww==";

        IvParameterSpec ivspec = new IvParameterSpec(myiv.getBytes());

        byte [] decoded;    
        FileWriter fstream = new FileWriter("out.txt");
        BufferedWriter out = new BufferedWriter(fstream);
        String mykey;
        int repeat = 256;

        outerloop:
        for(int i=0;i<repeat;i++){
            for(int j=0;j<repeat;j++){
                for(int k=0;k<repeat;k++){

                    mykey = new String(mykeyarray);

                    SecretKeySpec keyspec = new SecretKeySpec(mykey.getBytes(), "AES");

                    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

                    System.out.println("I: "+i+" J: "+j+" K: "+k); 

                    decoded = new BASE64Decoder().decodeBuffer(encoded); 

                    cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

                         byte [] decrypted = cipher.doFinal(decoded);
                         String dec = new String(decrypted);

                         if(dec.contains("Mary")){
                             out.write(dec);
                            out.write("\n");
                            System.out.println(dec);
                            break outerloop;
                         }

                            mykeyarray[15]++;
                }
                mykeyarray[14]++;
                mykeyarray[15]=0x00;
            }
            mykeyarray[13]++;
            mykeyarray[14]=0x00;
            mykeyarray[15]=0x00;
        }
            out.close();
    }

    catch(Exception e){
        System.out.println("Error: " + e.getMessage());
    }
}

}

3 ответа

Решение

Попробуйте узнать больше о заполнении PKCS#5. Это специальные байты, добавляемые в простой текст перед шифрованием. Это не может быть правильно, если текст был расшифрован с неправильным ключом. Если вы перебираете ключ, вы получите эту ошибку для каждого ключа, кроме правильного.

Ваш код делает много ошибок, и я не знаю, что вы пытаетесь сделать. Поэтому я объясню, почему вы можете получить BadPaddingException для шифра CBC:

  • Ваш ключ неверен
  • один или оба из последних двух блоков зашифрованного текста были изменены
  • один или несколько блоков были удалены из конца зашифрованного текста
  • IV неверен и зашифрованный текст состоит из одного блока

Удачи в поисках причины исключения.

Поскольку дешифрование случайным ключом дает вам случайное сообщение, вы обычно не получаете правильного заполнения. Просто поймайте исключение и двигайтесь дальше.

Вы получите ошибки заполнения примерно в 93% случаев, когда грубое форсирование сообщения с добавлением PKCS5. PKCS5 дополняет ваше сообщение байтами, содержащими длину заполнения. Допустимое заполнение: 0x01, 0x2 0x02, 0x03 0x03 0x03, ...., 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF. Вероятность правильного заполнения в случайном сообщении составляет 1/16 + (1/16)^2 ... (1/16)^16 <.067. Это означает, что вы получаете неправильное заполнение примерно в 1-% 6,7 = 93% времени.

Другие вопросы по тегам