Расшифровка AES-128 CBC

Я написал этот код на Java, чтобы расшифровать зашифрованный текст. У меня есть ключ. Мне все кажется правильным, но у меня есть проблема, которую я объясню.
Вот мой код:

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

public class AES_CBC {

    public static void main(String[] args) throws Exception {

    byte[] keyBytes = new byte[] { 14, (byte) 0x0b, (byte) 0x41,
            (byte) 0xb2, (byte) 0x2a, (byte) 0x29, (byte) 0xbe,
            (byte) 0xb4, (byte) 0x06, (byte) 0x1b, (byte) 0xda,
            (byte) 0x66, (byte) 0xb6, (byte) 0x74, (byte) 0x7e, (byte) 0x14 };

    byte[] ivBytes = new byte[] { (byte) 0x4c, (byte) 0xa0, (byte) 0x0f,
            (byte) 0xf4, (byte) 0xc8, (byte) 0x98, (byte) 0xd6,
            (byte) 0x1e, (byte) 0x1e, (byte) 0xdb, (byte) 0xf1,
            (byte) 0x80, (byte) 0x06, (byte) 0x18, (byte) 0xfb, (byte) 0x28 };

    SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
    IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

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

    byte[] cipherText = new byte[] { (byte) 0x28, (byte) 0xa2, (byte) 0x26,
            (byte) 0xd1, (byte) 0x60, (byte) 0xda, (byte) 0xd0,
            (byte) 0x78, (byte) 0x83, (byte) 0xd0, (byte) 0x4e,
            (byte) 0x00, (byte) 0x8a, (byte) 0x78, (byte) 0x97,
            (byte) 0xee, (byte) 0x2e, (byte) 0x4b, (byte) 0x74,
            (byte) 0x65, (byte) 0xd5, (byte) 0x29, (byte) 0x0d,
            (byte) 0x0c, (byte) 0x0e, (byte) 0x6c, (byte) 0x68,
            (byte) 0x22, (byte) 0x23, (byte) 0x6e, (byte) 0x1d,
            (byte) 0xaa, (byte) 0xfb, (byte) 0x94, (byte) 0xff,
            (byte) 0xe0, (byte) 0xc5, (byte) 0xda, (byte) 0x05,
            (byte) 0xd9, (byte) 0x47, (byte) 0x6b, (byte) 0xe0,
            (byte) 0x28, (byte) 0xad, (byte) 0x7c, (byte) 0x1d, (byte) 0x81 };

    cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
    byte[] original = cipher.doFinal(cipherText);
    String plaintext = new String(original);
    System.out.println(plaintext);
}
}

Я получаю ошибку ниже:

    Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:969)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:831)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
    at javax.crypto.Cipher.doFinal(Cipher.java:2097)
    at AES_CTR.main(AES_CBC.java:39)

Что происходит не так? Я знаю, что проблема как-то связана с заполнением, но я не знаю точного решения. У меня есть только один зашифрованный текст, IV и ключ.


person samantha    schedule 16.07.2014    source источник


Ответы (1)


Ваш первый keyByte неверен, он должен быть 0x14 вместо 14. Таким образом, байты заполнения расшифровываются неправильно, и блок считается неправильно заполненным.

См. параметры шифрования для возможных вариантов шифрования. опции.

person Kayaman    schedule 16.07.2014
comment
Java использует имя PKCS5Padding для обозначения схемы заполнения, которая не ограничивается размером блока 8 байт. По сути, алгоритм представляет собой дополнение PKCS7 с несколько неудачным названием. - person Oleg Estekhin; 16.07.2014
comment
@OlegEstekhin Хорошо, но в данном конкретном случае отступ не PKCS5 или PKCS7, а ISO10126. - person Kayaman; 16.07.2014
comment
Ты неправ. Последний блок заканчивается восемью байтами 0x08. Это является дополнением PKCS5/PKCS7. ISO10126 закончился бы одним 0x80 и семью 0x00. - person Oleg Estekhin; 16.07.2014
comment
@Oleg Я не знаю, что вы видите, нет ни восьми байтов 0x08, ни одного 0x80 и семи 0x00. Кроме того, я проверил это на своем компьютере, так что вам лучше взять себя в руки. - person Kayaman; 16.07.2014
comment
Вам лучше научиться расшифровывать последний блок зашифрованного текста, как если бы это был промежуточный блок. Расшифровка последних 16 байт рассматриваемого зашифрованного текста приведет к блоку данных, в котором заполнение PKCS5/7 очевидно. - person Oleg Estekhin; 16.07.2014
comment
Ааааа, теперь я понимаю, о чем ты говоришь. См. мой комментарий о том, что ключ неверен. Однако использование заполнения ISO10126 также будет правильно расшифровывать его, не вызывая исключения. - person Kayaman; 16.07.2014
comment
Я перепутал ISO10126 с ISO/IEC 7816-4. Пэды ISO10126 с [(длина-1) x (случайные байты), длина] заполнения, пэды PKCS5/7 с [длиной x длина], поэтому ISO10126 действительно может без проблем принимать заполнение PKCS5/7. Но все же этот зашифрованный текст использует заполнение PKCS5/7 =). - person Oleg Estekhin; 16.07.2014
comment
Подтвердил смысл Олега по поводу набивки. Каяман, говорить кому-то взять себя в руки неприемлемо, особенно если вы ошибаетесь. - person Maarten Bodewes; 17.07.2014
comment
@owlstead Но проблема была не в отступах, а в неправильном ключе. Я попробовал другое заполнение (после того, как я изменил ключ), и, поскольку ISO10126 не проверяет байты заполнения, это сработало. Он был прав насчет набивки, но мой ответ остается в силе. - person Kayaman; 17.07.2014
comment
Хорошо, тогда я понизлю его, так как он содержит неверную информацию, которую вы, похоже, не хотите менять. - person Maarten Bodewes; 17.07.2014
comment
О, я могу отредактировать пост, не заморачивайтесь, так как вы даже не участвовали в этом вопросе. - person Kayaman; 17.07.2014