Ошибка BouncyCastle AES при обновлении до 1.45
Недавно обновлен с BC 1.34 до 1.45. Я декодирую некоторые ранее закодированные данные следующим образом:
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
При использовании BC 1.45 я получаю это исключение:
javax.crypto.BadPaddingException: pad block corrupted
at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:715)
at javax.crypto.Cipher.doFinal(Cipher.java:1090)
РЕДАКТИРОВАТЬ: Подробнее об этой проблеме. Я использую следующее для генерации сырых ключей из ключевой фразы:
KeyGenerator kgen = KeyGenerator.getInstance("AES", "BC");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(seed);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
Я обнаружил, что это приводит к двум разным значениям для BC 1,34 против 1,45.
Это также может быть не связано с BouncyCastle (я тестирую на Android 2.3)
3 ответа
Похоже, проблема в том, что SecureRandom не переносится через границу Froyo-Gingerbread. Этот пост описывает похожую проблему:
http://groups.google.com/group/android-security-discuss/browse_thread/thread/6ec015a33784b925
Я не уверен, что именно изменилось в SecureRandom, но я нашел единственный способ исправить это - перешифровать данные ключами, сгенерированными переносимым методом.
Я только что закончил выслеживать это. Это связано с исправлением ошибки в строке 320 (в источнике Gingerbread) файла SHA1PRNG_SecureRandomImpl.java в методе engineNextBytes(), где
bits = seedLength << 3 + 64;
был изменен на
bits = (seedLength << 3) + 64;
Очевидно, это была ошибка, которая была исправлена, но это означает, что при одинаковом начальном уровне SecureRandom будет генерировать разные данные до и после обработки пряниками.
У меня есть "исправить" для этого. Я украл достаточно кода из Android-7, чтобы иметь возможность генерировать случайные байты так же, как это делал SecureRandom. Я пытаюсь расшифровать мою информацию, и если она не удалась, используйте мой защищенный протокол SecureRandom, чтобы расшифровать ее. Тогда я, очевидно, могу перешифровать его, используя более новый SecureRandom, хотя я думаю о том, чтобы полностью отказаться от SecureRandom...
Согласно примечаниям к выпуску, это исправление было включено в версию 1.40:
Проверка PKCS7Padding не завершится ошибкой, если длина пэда будет 0. Это было исправлено.
Похоже, это может быть уместно.