SSLContext 初始化

2022-09-04 06:34:54

我正在查看参考指南,我需要获取一个实例才能创建一个,以便我可以使用它来启用安全性。JSSESSLContextSSLEngineNetty

要获取 的实例,我使用 .我看到该方法被多次覆盖,因此我可以选择要使用的协议和安全提供程序。SSLContextSSLContext.getInstance()

在这里,我可以看到可以使用的算法列表。我应该使用哪种算法来启用安全通信?

另外,由于可以指定要使用的安全提供程序,因此我应该使用哪个提供程序?

谢谢


答案 1

正如您在标准名称文档中看到的,所有条目(SSLv3,TLSv1.0,TLSv1.1,...)都说它们可能支持其他版本。

在实践中,在Oracle JDK(和OpenJDK)中,它们都是这样做的。如果你看一下源代码,这个类是用于TLS,SSL,SSLv3和TLS10的,用于TLSv1.1和TLSv1.2。所有这些都支持所有版本的SSL / TLS,默认情况下启用的内容会有所不同。TLS10ContextTLS11ContextTLS12Context

这可能与其他提供商或 JRE 供应商不同。当然,您应该选择一个至少会支持您要使用的协议版本的协议版本。

请注意,所使用的协议是稍后使用 SSLSocket.setEnabledProtocols(...) 或其等效项确定的。SSLEngine

作为一般规则,请使用尽可能高的版本号(SSLv3 < TLSv1.0 < TLSv1.1 ...),这可能取决于您要与哪些各方进行通信支持。


默认情况下启用哪些协议因 Oracle JRE 的确切版本而异。

OpenJDK 7u40-b43中查看sun.security.ssl.SunJSSE的源代码时,在协议方面只是(和)的别名。看看SSLContextImpl的各种实现(它们本身就是内部类):TLSTLSv1SSLSSLv3SSLContextSSLContextImpl

  • 所有协议都支持所有协议。
  • 默认情况下,所有协议都在服务器端启用。
  • 默认情况下启用的客户端协议各不相同:
    • TLS10Context(用于协议 、 、 、 ) 在客户端默认启用 SSLv3 到 TLSv1.0。SSLSSLv3TLSTLSv1
    • TLS11Context(用于协议 )默认情况下也会启用 TLSv1.1。TLSv1.1
    • TLS12Context(用于协议 )默认情况下也会启用 TLSv1.2。TLSv1.2
  • 如果启用了 FIPS,则不支持 SSL(因此默认情况下不启用)。

这在 Java 8 中与新的 jdk.tls.client.protocols 系统属性一起更改。

同样,在 OpenJDK 8u40-b25 中查看 sun.security.ssl.SunJSSE 的源代码时,协议 、以及 也使用 和 ,它们遵循与 Java 7 中相同的逻辑。SSLContextTLSv1TLSv1.1TLSv1.2TLS10ContextTLS11ContextTLS12Context

但是,协议不再与其中任何一个别名。相反,它使用依赖于系统属性中的值的TLSContext。来自 JSSE 参考指南TLSjdk.tls.client.protocols

要在客户端上启用特定的 SunJSSE 协议,请在引号内的逗号分隔列表中指定它们;然后,在客户端上禁用所有其他支持的协议。例如,如果此属性的值为“TLSv1,TLSv1.1”,则在客户端上启用 TLSv1 和 TLSv1.1 的默认协议设置,而在客户端上禁用 SSLv3、TLSv1.2 和 SSLv2Hello。

如果此属性为空,则默认情况下在客户端和服务器端启用所有协议。

当然,在最新版本的Oracle JRE 8中,SSL在默认情况下也是完全禁用的(因此从这些列表中删除)。

请注意,在这两种情况下(JRE 7 和 8),默认情况下通过开箱即用获得的您或多或少等同于使用协议获得并使用默认信任库参数进行初始化,依此类推。SSLContextSSLContext.getDefault()SSLContextTLS


答案 2

该协议没有默认值,因此我将使用JDK支持的最新协议,即TLSv1,TLSv1.1或TLSv1.2:看看哪个有效,或者看看。使用默认安全提供程序时,请避开指定它的所有 API,否则例如 .getSupportedProtocols()KeyStore.getDefaultType()

当您来获取SSLEngines时,请确保使用采用主机名和端口的方法。否则,您将无法获得SSL会话共享。