Я пишу приложение для Android 1.6.
Может ли кто-нибудь сказать мне, можно ли использовать последний провайдер Bouncy Castle (версия 1.46) вместо старого, содержащегося в SDK?
Если да, буду признателен за правильные инструкции.
Могу ли я использовать последний провайдер BouncyCastle на Android?
Ответы (3)
Обнаружена проблема в Google и SpongyCastle. После того, как я добавил jar и вызвал addProvider(), приложение стало больше, но могло использовать функции BC 1.46, такие как дайджест Whirlpool.
... платформа Android, к сожалению, включает урезанную версию Bouncy Castle, что также затрудняет установку обновленной версии библиотек из-за конфликтов загрузчика классов.
Если вам действительно нужна полная версия библиотек Bouncy Castle в вашем приложении для Android, вам может быть удобно использовать Spongy Castle — переупаковку Bouncy Castle для Android:
Тем временем Android изменил название пакета, и BC можно использовать в его последней версии. Но есть еще как минимум одна проблема:
Имя провайдера "BC" используется старой встроенной версией BC. Добавление BC с Security.addProvider(new BouncyCastleProvider(), 0)
в качестве первого провайдера может работать в простых случаях, но Android Pie представил неприятную проверку для BouncyCastleProvider, не допускающую несколько режимов, например. проверка пути сертификата X.509 не может быть реализована и некоторые другие алгоритмы. Эта проблема возникает, когда BC добавляется с Security.addProvider
до первого касания sun.security.jca.Providers
. Добавление BC в список провайдеров обычно требуется для возможности маршрутизации непрямых вызовов из другого кода, ссылающегося на BC на новую версию BC. Например. хранилище ключей PKCS12 использует в своем коде вызов для создания CertificateFactory
с использованием BC.
Чек находится в sun.security.jca.Providers
и называется, например. от java.security.cert.CertificateFactory
. Код не может отличить включенную версию Android BC от более новой рабочей версии. Хак для решения этой проблемы заключается в том, чтобы выполнить этот фрагмент кода раньше, когда приложение запускается. Код должен быть выполнен до того, как коснется sun.security.jca.Providers
, иначе фрагмент статического кода уже выполняется, читая существующие криптопровайдеры:
private static final String SUN_PROVIDERS = "sun.security.jca.Providers";
...
// remove BC provider first
Security.removeProvider("BC");
// also remove not sufficient AndroidOpenSSL provider for X.509 - most likely only needed if BouncyCastleJsseProvider is used
Security.removeProvider("AndroidOpenSSL");
// touch the internal Providers class to trigger the static provider loading
// see http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/sun/security/jca/Providers.java#SYSTEM_BOUNCY_CASTLE_PROVIDER
try {
Class.forName(SUN_PROVIDERS);
} catch (ClassNotFoundException e) {
throw new RuntimeException(String.format("%s to patch not found.", SUN_PROVIDERS), e);
}
// insert modern BC as first crypto provider
Security.insertProviderAt(new BouncyCastleProvider(), 0);
Вы должны иметь возможность, по крайней мере, использовать облегченную криптографическую библиотеку. Найдите lcrypto-jdk* на странице релизов. Признаюсь, у меня нет тестовой среды Android, чтобы проверить что-либо из этого. Обратите внимание, что эта версия библиотеки не использует JCE API.