简体   繁体   English

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

[英]create an SSLContext instance using a Bouncy Castle provider

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):我一直在创建 SSLContext(我想用它来实例化 SSLEngine 以通过 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.我将 Bouncy Castle 的当前提供程序包“bcprov-jdk15on-150.jar”(我从这里获得)附加到应用程序类路径及其引导类路径(通过 VM-Option -Xbootclasspath/p),但都没有解决问题。 I also tried different values for protocol (ie 'SSL' and 'TLSv1') without any effect.我还尝试了不同的protocol值(即“SSL”和“TLSv1”),但没有任何效果。

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.但与它们相反,我的目标是(并且我正在使用)Java 7(或更高版本),但我仍然有这个问题。 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)?一般来说,以这种方式使用 Bouncy Castle 是否可行,或者我是否必须使用他们各自的 API 而不是 oracle 的NIO 通过 SSLEngine重写我的协议(这是我现在正在做的方式)?

Thank you so much for any help here.非常感谢您在这里提供的任何帮助。

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 [?] [是否可以] 使用 Bouncy Castle 提供程序创建 SSLContext 实例 [?]
  • No

Why not?为什么不?

Debugging this line of code:调试这行代码:

Provider [] providers = Security.getProviders();
  • the default SunJSSE version 1.7 implements the following SSLContext values:默认的 SunJSSE 版本 1.7 实现以下 SSLContext 值:

    Alg.Alias.SSLContext.SSL=TLSv1 Alg.Alias.SSLContext.SSL=TLSv1
    Alg.Alias.SSLContext.SSLv3=TLSv1 Alg.Alias.SSLContext.SSLv3=TLSv1
    SSLContext.Default=sun.security.ssl.SSLContextImpl$DefaultSSLContext SSLContext.Default=sun.security.ssl.SSLContextImpl$DefaultSSLContext
    SSLContext.TLSv1=sun.security.ssl.SSLContextImpl$TLS10Context SSLContext.TLSv1=sun.security.ssl.SSLContextImpl$TLS10Context
    SSLContext.TLSv1.1=sun.security.ssl.SSLContextImpl$TLS11Context SSLContext.TLSv1.1=sun.security.ssl.SSLContextImpl$TLS11Context
    SSLContext.TLSv1.2=sun.security.ssl.SSLContextImpl$TLS12Context 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.使用 bcprov-jdk15on-152.jar 并将新的 BouncyCastleProvider() 添加到 Security,可以观察到没有可用的 SSLContext 值。

This should make sense since Bouncy Castle is a JCE implementation, not a JSSE implementation.这应该是有道理的,因为 Bouncy Castle 是一个JCE实现,而不是一个JSSE实现。

Bouncy Castle actually provides a JSSE implementation as of version 1.56. Bouncy Castle 实际上提供了 1.56 版的 JSSE 实现。 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:或者,作为替代,在全局<JRE_HOME>/lib/security/java.security文件中:

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:然后您可以将它与标准 API 一起使用:

SSLContext context = SSLContext.getInstance("TLS");

Bouncy Castle implements two types of providers for JSSE: Bouncy Castle 为 JSSE 实现了两种类型的提供程序:

  • An ordinary DTLS/TLS and JSSE provider package一个普通的DTLS/TLS 和 JSSE 提供程序包
  • A FIPS-compliant (D)TLS API and JSSE Provider符合 FIPS 的(D)TLS API 和 JSSE 提供程序

Current documentation for each provider can be found here: ordinary and FIPS-compliant .可以在此处找到每个提供程序的当前文档:普通符合 FIPS 的

The JAR files for these differ from the JAR file for Bouncy Castle JCE provider.这些 JAR 文件不同于 Bouncy Castle JCE 提供程序的 JAR 文件。 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 .在撰写本文时,JSSE 提供程序 JAR 文件称为bctls-jdk15on-1.64.jarbctls-fips-1.0.9.jar ,而 JCE 提供程序bcprov-jdk15on-1.64.jar

Here's an excerpt from the documentation:以下是文档的摘录:

2.1 BCJSSE Provider installation into the JRE 2.1 BCJSSE Provider安装到JRE

Once the bctls jar is installed, the provider class BouncyCastleJsseProvider may need to be installed if it is required in the application globally.安装 bctls jar 后,如果应用程序全局需要提供程序类 BouncyCastleJsseProvider,则可能需要安装它。

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.通过将提供者定义添加到 JRE/JDK 的jre/lib/security目录中的java.security文件中,可以在 JVM 中静态完成提供者的安装。

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:如果您希望在执行期间将提供程序全局添加到 JVM,您可以将以下导入添加到您的代码中:

 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:然后可以通过引用名称BCJSSE来使用提供者,例如:

 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.或者,如果您不想全局安装提供程序,而是在本地使用它,则可以将提供程序传递给您正在为其创建实例的 JSSE 类上的getInstance()方法。

For example:例如:

 SSLContext clientContext = SSLContext.getInstance("TLS", new BouncyCastleJsseProvider());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM