SSLContext初始化

时间:2012-07-16 12:18:37

标签: java security ssl jsse

我正在查看JSSE参考指南,我需要获取SSLContext的实例才能创建SSLEngine,因此我可以将其与Netty一起使用启用安全性。

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

Here,我可以看到可以使用的算法列表。我应该使用哪种算法来实现安全通信?

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

由于

2 个答案:

答案 0 :(得分:27)

正如您在standard names documentation中所看到的,所有条目(SSLv3,TLSv1.0,TLSv1.1,...)都表示它们可能支持其他版本。

实际上,在Oracle JDK(和OpenJDK)中,他们都这样做。如果您查看source codeTLS10Context类是用于TLS,SSL,SSLv3和TLS10的类,TLS11Context用于TLSv1.1,TLS12Context用于TLSv1。 2。所有版本都支持所有版本的SSL / TLS,默认情况下启用的内容会有所不同。

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

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

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


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

在查看the source code for sun.security.ssl.SunJSSE in OpenJDK 7u40-b43时,TLS只是TLSv1的别名(SSLSSLv3也是如此),{{1}协议。查看各种implementations of SSLContextImplSSLContext本身的内部类):

  • 全部支持所有协议。
  • 默认情况下,在服务器端启用所有协议。
  • 默认启用的客户端协议有所不同:
    • SSLContextImpl(用于协议TLS10ContextSSLSSLv3TLS)默认情况下在客户端启用SSLv3到TLSv1.0。< / LI>
    • TLSv1(用于协议TLS11Context)默认情况下也会启用TLSv1.1。
    • TLSv1.1(用于协议TLS12Context)默认情况下也会启用TLSv1.2。
  • 如果启用了FIPS,则不支持SSL(默认情况下不启用)。

这在Java 8中与the new jdk.tls.client.protocols系统属性一起发生了变化。

同样,在查看the source code for sun.security.ssl.SunJSSE in OpenJDK 8u40-b25时,TLSv1.2协议SSLContextTLSv1TLSv1.1也会使用TLSv1.2,{{ 1}}和TLS10Context,遵循与Java 7中相同的逻辑。

但是,协议TLS11Context不再是其中任何一个的别名。相反,它使用TLSContext,它依赖于TLS12Context系统属性中的值。来自JSSE Reference guide

  

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

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

当然,在recent versions of Oracle JRE 8, SSL is also completely disabled by default中(已从这些列表中移除)。

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

答案 1 :(得分:3)

协议没有默认值,因此我将使用JDK支持的最新版本,即TLSv1,TLSv1.1或TLSv1.2:查看哪些有效,或查看getSupportedProtocols() 。通过避免指定它的所有API来使用默认安全提供程序,或者例如KeyStore.getDefaultType()

当你来获取SSLEngine时,请确保使用带有主机名和端口的方法。否则,您将无法获得SSL会话。