12

我坚持创建 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 是否可行,或者我是否必须通过 SSLEngine 使用它们各自的 API 而不是 oracle 的 NIO重写我的协议(这是我现在正在做的方式)?

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

4

3 回答 3

12

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

  • [是否可以] 使用 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 并向 Security 添加一个新的 BouncyCastleProvider(),可以观察到没有可用的 SSLContext 值。

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

于 2015-05-22T20:50:09.720 回答
8

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");
于 2017-06-27T13:20:07.967 回答
1

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安装到JRE

安装 bctls jar 后,如果应用程序全局需要提供程序类 BouncyCastleJsseProvider,则可能需要安装它。

通过将提供程序定义添加到JRE/JDK 目录中的java.security文件中,可以在 JVM 中静态安装提供程序。jre/lib/security

也可以在执行期间添加提供程序。如果您希望在执行期间将提供程序全局添加到 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());
于 2020-04-05T18:35:31.323 回答