создать экземпляр SSLContext с помощью провайдера Bouncy Castle

Я застрял при создании SSLContext (который я хочу использовать для создания экземпляра SSLEngine для обработки зашифрованного транспорта через java-nio):

Код

String protocol = "TLSv1.2";
Provider provider = new BouncyCastleProvider();
Security.addProvider(provider);
sslContext = SSLContext.getInstance(protocol,provider.getName());

выдает следующее исключение:

Exception in thread "main" java.lang.RuntimeException: java.security.NoSuchAlgorithmException: no such algorithm: SSL for provider BC
at org.bitmash.network.tcp.ssl.SslTransferFactory.<init>(SslTransferFactory.java:43)
at org.bitmash.network.http.HttpsServer.<init>(HttpsServer.java:19)

Я прикрепил текущий пакет провайдера Bouncy Castle 'bcprov-jdk15on-150.jar' (который я получил от здесь) к пути к классам приложений, а также к его пути к классу загрузки (через VM-Option -Xbootclasspath/p), но ни один из них не решил проблему. Я также пробовал разные значения для protocol (например, «SSL» и «TLSv1») без какого-либо эффекта.

Также я нашел людей с похожими проблемами здесь и здесь. Но в отличие от них, я нацелен (и использую) Java 7 (или выше), но у меня все еще есть эта проблема. Возможно ли вообще использовать Bouncy Castle таким образом, или мне нужно переписать свой протокол, используя соответствующий API вместо NIO через SSLEngine (именно так я делаю это прямо сейчас)?

Большое спасибо за любую помощь здесь.


person Sebastian Schmitt    schedule 28.05.2014    source источник


Ответы (3)


Я знаю, что это старый вопрос, но мне нужен был ответ (поэтому я создаю его):

  • [Возможно ли] создать экземпляр SSLContext с помощью провайдера Bouncy Castle [?]
  • No

Почему бы и нет?

Отладка этой строки кода:

Provider [] providers = Security.getProviders();
  • версия SunJSSE 1.7 по умолчанию реализует следующие значения SSLContext:
    #P4#
  • используя bcprov-jdk15on-152.jar и добавляя новый BouncyCastleProvider() в Security, можно заметить, что нет доступных значений SSLContext.

Это должно иметь смысл, поскольку Bouncy Castle — это реализация JCE, а не JSSE.

person k2zinger    schedule 22.05.2015
comment
С другой стороны, если вы пытались создать ключ с помощью KeyGenerator, то BC отлично подходит для этого! KeyGenerator.getInstance(Threefish-256,BC) или KeyGenerator.getInstance(HMACSHA512/224,BC) - вы поняли... - person k2zinger; 22.05.2015

Bouncy Castle фактически предоставляет реализацию JSSE начиная с версии 1.56. Просто не забудьте настроить его с более высоким приоритетом при запуске приложения:

Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);

или, как вариант, в глобальном <JRE_HOME>/lib/security/java.security файле:

security.provider.1=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
...
security.provider.6=com.sun.net.ssl.internal.ssl.Provider

Затем вы можете использовать его со стандартным API:

SSLContext context = SSLContext.getInstance("TLS");
person Mateusz Klara    schedule 27.06.2017
comment
И обратите внимание, что это отдельная банка -- bctls-$version не (просто) bcprov-$version . - person dave_thompson_085; 09.08.2017

Bouncy Castle реализует два типа провайдеров для JSSE:

Текущую документацию для каждого провайдера можно найти здесь: обычный и совместимо с FIPS.

Файлы JAR для них отличаются от файлов JAR для поставщика JCE Bouncy Castle. На момент написания этих строк JAR-файлы поставщика JSSE назывались bctls-jdk15on-1.64.jar и bctls-fips-1.0.9.jar, а поставщик JCE — bcprov-jdk15on-1.64.jar.

Вот выдержка из документации:

2.1 Установка BCJSSE Provider в JRE

После установки jar bctls может потребоваться установить класс провайдера BouncyCastleJsseProvider, если он требуется в приложении глобально.

Установку провайдера можно выполнить статически в JVM, добавив его в определение провайдера в файл java.security в каталоге jre/lib/security для вашего JRE/JDK.

Поставщик также может быть добавлен во время выполнения. Если вы хотите добавить поставщика в JVM глобально во время выполнения, вы можете добавить в свой код следующие импорты:

import java.security.Security
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider

Затем вставьте строку

Security.addProvider(new BouncyCastleJsseProvider());

Затем поставщика можно использовать, указав имя BCJSSE, например:

SSLContext clientContext = SSLContext.getInstance("TLS", "BCJSSE");

В качестве альтернативы, если вы не хотите устанавливать поставщик глобально, а вместо этого используете его локально, можно передать поставщик методу getInstance() в классе JSSE, экземпляр которого вы создаете.

Например:

SSLContext clientContext = SSLContext.getInstance("TLS",
       new BouncyCastleJsseProvider());
person M.S. Dousti    schedule 05.04.2020