Ошибка 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)


person sehugg    schedule 10.12.2010    source источник


Ответы (3)


Я только что закончил отслеживать это. Это связано с исправлением ошибки в строке 320 (в исходном коде Gingerbread) SHA1PRNG_SecureRandomImpl.java в методе engineNextBytes(), где

bits = seedLength << 3 + 64;

был изменен на

bits = (seedLength << 3) + 64;

Ясно, что это была исправленная ошибка, но это означает, что при одном и том же начальном числе SecureRandom будет генерировать разные данные до и после имбирного пряника.

У меня есть "исправление" для этого. Я украл достаточно кода из Android-7, чтобы иметь возможность генерировать случайные байты так же, как это делал SecureRandom. Я пытаюсь расшифровать свою информацию, и если это не удается, я использую для ее расшифровки мой навороченный SecureRandom. Тогда я, очевидно, смогу перешифровать его, используя более новый SecureRandom, хотя я как бы подумываю полностью отказаться от SecureRandom...

person Ben Demboski    schedule 18.03.2011
comment
Я пытаюсь реализовать то же самое... Как вы создали провайдера? - person William Melani; 01.07.2011
comment
@Ben Demboski, не могли бы вы опубликовать свой обходной путь? это было бы наиболее полезно - person pandre; 18.11.2012

Похоже, проблема в том, что SecureRandom не переносится через границу Froyo-Gingerbread. Этот пост описывает аналогичную проблему:

http://groups.google.com/group/android-security-discuss/browse_thread/thread/6ec015a33784b925

Я не уверен, что именно изменилось в SecureRandom, но единственный способ исправить это — повторно зашифровать данные ключами, сгенерированными переносимым методом.

person sehugg    schedule 10.12.2010
comment
Ты прав. Контракт для SecureRandom не обещает, что начальное число, которое вы указываете вручную, будет единственным начальным числом, которое он использует. Он будет использовать другие источники, такие как /dev/random в linux/bsd. - person President James K. Polk; 11.12.2010
comment
Для будущих читателей: другими словами, вместо этого используйте хорошо известный метод получения ключей, такой как PBKDF2. - person Maarten Bodewes; 14.02.2012

Согласно примечаниям к выпуску, это исправление было включено в версию 1.40:

Проверка PKCS7Padding не завершалась ошибкой, если длина пэда была равна 0. Это было исправлено.

Это звучит так, как будто это может быть уместно.

person caf    schedule 10.12.2010