我使用不同模式的 AES 加密(以下,示例中的“CBC”模式)。我用文本加密以下文件。
我大约在文本中间向生成的加密代码中引入了一个错误。
解密后得到如下文字。

实际上,问题是:为什么这部分文本被错误地解密了,因为,正如我从 AES 文档中理解的那样(正如老师向我解释的那样),在引入错误之后包含的所有文本都应该被错误地解密?如何让它完全像这样工作?
类代码(在“模式”中我通过模式):
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;
}
一切都是正确的。AES 以块的形式处理数据。在 CBC 模式下,使用 2 个密文块来解密一个块。它看起来像这样:
因此,1 字节密文的错误将导致仅对一个块进行错误解密。在另一个块中加上一个字节(因为 xor 操作)。
如果您需要在出错后破坏所有块,您可以使用不同的加密模式,例如 PCBC 具有此属性。