Шифрование 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, вы можете перенести его. Успешная миграция указывается и дополнительное поле, которое сохраняется.