AES. javax.crypto.Cipher возвращает пустой массив в режиме расшифровки
Я сам внедряю режим CBC. И я использую AES как функцию E для каждого блока CBC.
Вот мой код шифрования:
public static List<Byte> encrypt(List<Byte> bytes, byte[] key) throws Exception {
byte[] bytesArray = BytesConverter.toByteArray(bytes);
SecretKey secretKey = new SecretKeySpec(key, AES);
Cipher cipher = Cipher.getInstance(AES);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return BytesConverter.toByteList(cipher.update(bytesArray));
}
я использую update
потому что я не хочу добавлять панель AES. Я делаю это сам для последнего блока в начале алгоритма CBC.
Когда я хочу расшифровать блок зашифрованного текста, я использую ту же функцию с Cipher.DECRYPTION_MODE.
public static List<Byte> decrypt(List<Byte> bytes, byte[] key) throws Exception {
byte[] bytesArray = BytesConverter.toByteArray(bytes);
SecretKey secretKey = new SecretKeySpec(key, AES);
Cipher cipher = Cipher.getInstance(AES);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return BytesConverter.toByteList(cipher.update(bytesArray));
}
Проблема в том, что Cipher.update
в режиме расшифровки возвращает пустой байтовый массив для ввода, который был зашифрован encrypt
метод.
Я не совсем понимаю. В чем дело?
1 ответ
Вы пропускаете звонок doFinal
, Из-за заполнения для шифрования в режиме ECB и CBC, Cipher
экземпляры необходимы для буферизации до размера блока - 1 байта, который будет дополнен и зашифрован (или расшифрован и не дополнен) в doFinal()
вызов, который освобождает последнюю часть зашифрованного текста (или открытого текста для расшифровки).
Что вы должны сделать, это использовать "AES/ECB/NoPadding"
и только doFinal
вместо update
реализовать CBC для каждого блока (хотя просто update
тоже может работать, но это не на 100% указано, что должно). Это идентично блочному шифрованию базового шифра AES. Вы также можете использовать более легкий (то есть: прямой, не JCE) API нижнего уровня Bouncy Castle, который предоставляет механизмы AES, которые просто реализуют сам блочный шифр.