Шифрование PBE AES_256 несовместимо между java 8 u65 и u71
У меня есть текст, зашифрованный и хранящийся в db с помощью PBE AES_256
. Сначала это было сделано с помощью java 1.8.0_65
. После обновления до последней java я больше не могу расшифровать эти поля. Я указал несовместимость на 1.8.0_71
. В примечаниях к выпуску указано следующее:
Проблема с алгоритмами PBE с использованием AES crypto corrected Ошибка была исправлена для PBE с использованием 256-битных AES-шифров, так что производный ключ может быть другим и не эквивалентен ключам, ранее полученным от одного и того же пароля. JDK-8138589 (не публичный)
Поэтому я предполагаю, что мне нужно перенести эти значения полей "вручную", дешифруя со старой версией, сохраняя равное значение и впоследствии повторно шифруя текущую версию. Есть ли лучший способ сделать это, или мне, возможно, не хватает чего-то относительно этой несовместимости?
Вот часть кода, который используется для шифрования:
SecretKey keyFromPassword =
SecretKeyFactory.getInstance(
algorithm).generateSecret(
new PBEKeySpec(password.toCharArray()));
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, keyFromPassword, new PBEParameterSpec(
salt, iterations, new IvParameterSpec(iv)));
IOUtils.copyLarge(new CipherInputStream(clearStream, cipher), encryptedStream);
Решение
Я смог расшифровать существующие значения, сделав магию отражения на моем шифре и повторно инициализируя его. Вот код, если кому-то интересно:
Object spi = ReflectionTestUtils.getField(cipher, "spi");
ReflectionTestUtils.setField(spi, "keyLength", 128);
cipher.init(Cipher.DECRYPT_MODE, keyFromPassword, new PBEParameterSpec(
salt, iterations, new IvParameterSpec(iv)));
Ответы
Ответ 1
Миграция значений поля звучит как разумный подход.
Глядя на фактическое изменение кода, связанное с JDK-8138589 не выглядит слишком сложным.
Разница, по-видимому, составляет только длину ключа. Поэтому вы должны иметь возможность воспроизводить старое значение даже в версиях после 1.8.0_71.
Если вы обнаружите значение, созданное со старой версией Java, но теперь запущен на "новой" версии Java, вы можете перенести его. Успешная миграция указывается и дополнительное поле, которое сохраняется.