有人告诉我,理想情况下,初始化向量应该是随机生成的(我还在某处读到过这个),但如果每次都是随机生成的,那么数据将被错误地解密,对吧?你什么意思我没听懂?这是我的加密和解密代码
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 + "/NoPadding");
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;
}
// генерация инициализирующего вектора
private static String genInitVector() {
Random r = new Random();
StringBuilder builder = new StringBuilder();
for (int j = 0; j < 16; j++) {
char code = (char) (r.nextInt(94) + 33); // символы с кодами от 33 по 126
builder.append(Character.toString(code));
}
return builder.toString();
}
}
通常 IV 与加密消息一起传输(不太常见的是根据某些数据计算)。可以在加密数据之前的开头插入 16 个字节 IV。这不会以任何方式影响安全性。
您可以使用以下方法获取正确的 IV
SecureRandom: