#java #криптография #шифрование #aes
Использую шифрование AES с разными режимами (далее в примере режим "CBC"). Зашифровываю следующий файл с текстом. Вношу ошибку в получившийся шифрованный код примерно в середине текста. При дешифровке получается следующий текст. Собственно вопрос: почему неправильно расшифровывается именно этот отрезок текста, ведь как я понял из документации AES (и как мне объяснял преподаватель) неправильно расшифровываться должен весь текст, содержащийся после внесенной ошибки? Как сделать, чтобы работало именно так? Код класса (в "mode" передаю режим): public class AesCipher { private static final String INIT_VECTOR = "ItIsOurBigSecret"; // зашифрование static byte[] encrypt(byte[] secretKey, byte[] plainText, String mode) { try { if (!isKeyLengthValid(secretKey)) { throw new Exception("Длина ключа должна быть 128, 192 или 256 бит!"); } IvParameterSpec ivParameterSpec = new IvParameterSpec(INIT_VECTOR.getBytes()); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "AES"); Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding"); if (mode.equals("ECB")) cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); else cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); return cipher.doFinal(plainText); } catch (Throwable cause) { System.out.print(cause.getMessage()); } return null; } // дешифрование static byte[] decrypt(byte[] secretKey, byte[] cipherText, String mode) { try { if (!isKeyLengthValid(secretKey)) { throw new Exception("Длина ключа должна быть 128, 192 или 256 бит!"); } IvParameterSpec ivParameterSpec = new IvParameterSpec(INIT_VECTOR.getBytes()); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "AES"); Cipher cipher = Cipher.getInstance("AES/" + mode + "/PKCS5Padding"); if (mode.equals("ECB")) cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); else cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); return cipher.doFinal(cipherText); } catch (Throwable cause) { System.out.print(cause.getMessage()); Controller.ShowMessage(cause.getMessage()); } return null; } // проверка длины ключа private static boolean isKeyLengthValid(byte[] key) { return key.length == 16 || key.length == 24 || key.length == 32; }
Ответы
Ответ 1
Все правильно. AES обрабатывает данные блоками. В режиме CBC для расшифровки одного блока используется 2 блока шифротекста. Выглядит это приблизительно так: расшифрованый_блок = aes_decrypt(зашифрованый_блок) xor (предыдущий_зашифр_блок) По-этому ошибка в 1 байте шифротекста приведет к неправильной расшифровке только одного блока. Плюс один байт в другом блоке (из-за операции xor). Если вам нужно, что бы ломались все блоки после ошибки, можете использовать другой режим шифрования, например PCBC обладает таким свойством.
Комментариев нет:
Отправить комментарий