SSLContext初始化

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

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

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

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

谢谢

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

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

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

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

作为一般规则,请使用最高版本号(SSLv3


默认情况下启用哪些协议取决于Oracle JRE的确切版本。

在OpenJDK 7u40-b43中查看sun.security.ssl.SunJSSE的源代码时,就SSLSontext TLSTLS只是TLSv1一个别名( SSLSSLv3也是如此)。 查看SSLContextImpl的各种实现 (它们是SSLContextImpl本身的内部类):

  • 所有协议都支持。
  • 默认情况下,在服务器端启用所有协议。
  • 默认情况下启用的客户端协议有所不同:
    • TLS10Context (用于协议SSLSSLv3TLSTLSv1 )默认在客户端启用SSLv3到TLSv1.0。
    • 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的源代码时 , SSLContext协议TLSv1TLSv1.1TLSv1.2也使用TLS10ContextTLS11ContextTLS12Context ,它们遵循相同的逻辑。在Java 7中。

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

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

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

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

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

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

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