使用Bouncy Castle提供程序创建SSLContext实例

13

我卡在创建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选项-Xbootclasspath/p),但两者都没有解决问题。我还尝试了不同的protocol值(即'SSL'和'TLSv1'),但没有任何效果。

此外,我在这里这里找到了类似问题的人。但与他们相反,我针对并使用Java 7(或更高版本),但我仍然有这个问题。总的来说,使用Bouncy Castle这种方式是可行的吗,还是我必须重写我的协议,使用它们各自的API而不是通过SSLEngine使用oracle的NIO(这是我现在正在使用的方法)?

非常感谢您在这里的任何帮助。

3个回答

13

我知道这是一个有点老的问题,但我需要一个答案(所以我正在创建一个):

  • 是否可以使用Bouncy Castle提供程序创建SSLContext实例?
  • 不行

为什么不行?

调试这行代码:

Provider [] providers = Security.getProviders();
  • 默认的SunJSSE版本1.7实现了以下SSLContext值:

    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

  • 使用bcprov-jdk15on-152.jar并将新的BouncyCastleProvider()添加到Security中,可以发现没有可用的SSLContext值。

这是有道理的,因为Bouncy Castle是JCE实现,而不是JSSE实现。


另一方面,如果您想使用KeyGenerator创建密钥,那么BC非常适合这样做!KeyGenerator.getInstance("Threefish-256","BC")或KeyGenerator.getInstance("HMACSHA512/224","BC") - 你懂的... - k2zinger

10
Bouncy Castle实际上从版本1.56开始提供了JSSE实现。只需确保在应用程序启动时为其配置更高的优先级即可:
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");

3
请注意,这是一个单独的jar包 -- bctls-$version 而不是(仅仅)bcprov-$version。 - dave_thompson_085

3

Bouncy Castle实现了两种JSSE提供程序:

  • 普通的DTLS/TLS和JSSE提供程序包
  • FIPS兼容(D)TLS API和JSSE提供程序

每个提供程序的当前文档可以在此处找到:普通FIPS兼容

这些JAR文件与Bouncy Castle JCE提供程序的JAR文件不同。在撰写本文时,JSSE提供程序JAR文件分别为bctls-jdk15on-1.64.jarbctls-fips-1.0.9.jar,而JCE提供程序则为bcprov-jdk15on-1.64.jar

以下是文档摘录:

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());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接