12

I'm stuck at the creation of an SSLContext (which I want to use to instantiate an SSLEngine to handle encrypted transport via the java-nio):

The code

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

throws the following exception:

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)

I attached Bouncy Castle's current provider package 'bcprov-jdk15on-150.jar' (which I got from here) to the applications classpath as well as to its bootclasspath (via VM-Option -Xbootclasspath/p), but neither solved the problem. I also tried different values for protocol (i. e. 'SSL' and 'TLSv1') without any effect.

Also, I found people with similar problems here and here. But in contrast to them, I'm targeting (and I'm using) Java 7 (or greater), but I still have this problem. Is it -in general- even feasible to use Bouncy Castle this way, or do I have to rewrite my protocol using their respective API instead of oracle's NIO via SSLEngine (which is the way I'm doing it right now)?

Thank you so much for any help here.

Sebastian Schmitt
  • 433
  • 1
  • 5
  • 18

3 Answers3

13

I know this is kind of an old question, but I needed an answer (so I am creating one):

  • [Is it possible to] create an SSLContext instance using a Bouncy Castle provider [?]
  • No

Why not?

Debugging this line of code:

Provider [] providers = Security.getProviders();
  • the default SunJSSE version 1.7 implements the following SSLContext values:

    Alg.Alias.SSLContext.SSL=TLSv1
    Alg.Alias.SSLContext.SSLv3=TLSv1
    SSLContext.Default=sun.security.ssl.SSLContextImpl$DefaultSSLContext
    SSLContext.TLSv1=sun.security.ssl.SSLContextImpl$TLS10Context
    SSLContext.TLSv1.1=sun.security.ssl.SSLContextImpl$TLS11Context
    SSLContext.TLSv1.2=sun.security.ssl.SSLContextImpl$TLS12Context

  • using bcprov-jdk15on-152.jar and adding a new BouncyCastleProvider() to Security, one can observe that there are no SSLContext values available.

This should make sense since Bouncy Castle is a JCE implementation, not a JSSE implementation.

k2zinger
  • 382
  • 7
  • 15
  • Now on the other hand, if you were trying to create a key with KeyGenerator, then BC is great for doing that! KeyGenerator.getInstance("Threefish-256","BC") or KeyGenerator.getInstance("HMACSHA512/224","BC") - you get the point... – k2zinger May 22 '15 at 20:50
8

Bouncy Castle actually provides a JSSE implementation as of version 1.56. Just make sure to configure it with a higher priority at the application startup:

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

or, as alternative, in global <JRE_HOME>/lib/security/java.security file:

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

You can use it then with the standard API:

SSLContext context = SSLContext.getInstance("TLS");
user11153
  • 8,536
  • 5
  • 47
  • 50
Mateusz Klara
  • 93
  • 1
  • 6
2

Bouncy Castle implements two types of providers for JSSE:

  • An ordinary DTLS/TLS and JSSE provider package
  • A FIPS-compliant (D)TLS API and JSSE Provider

Current documentation for each provider can be found here: ordinary and FIPS-compliant.

The JAR files for these differ from the JAR file for Bouncy Castle JCE provider. At the time of these writing, the JSSE provider JAR files are called bctls-jdk15on-1.64.jar and bctls-fips-1.0.9.jar, whereas the JCE provider is bcprov-jdk15on-1.64.jar.

Here's an excerpt from the documentation:

2.1 BCJSSE Provider installation into the JRE

Once the bctls jar is installed, the provider class BouncyCastleJsseProvider may need to be installed if it is required in the application globally.

Installation of the provider can be done statically in the JVM by adding it to the provider definition to the java.security file in in the jre/lib/security directory for your JRE/JDK.

The provider can also be added during execution. If you wish to add the provider to the JVM globally during execution you can add the following imports to your code:

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

Then insert the line

Security.addProvider(new BouncyCastleJsseProvider());

The provider can then be used by referencing the name BCJSSE, for example:

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

Alternately if you do not wish to install the provider globally, but use it locally instead, it is possible to pass the provider to the getInstance() method on the JSSE class you are creating an instance of.

For example:

SSLContext clientContext = SSLContext.getInstance("TLS",
       new BouncyCastleJsseProvider());
Sadeq Dousti
  • 3,346
  • 6
  • 35
  • 53