我正在查看JSSE
参考指南,我需要获取SSLContext
的实例才能创建SSLEngine
,因此我可以将其与Netty
一起使用启用安全性。
要获取SSLContext
的实例,我使用SSLContext.getInstance()
。我看到该方法被多次覆盖,因此我可以选择使用协议和安全提供程序。
Here,我可以看到可以使用的算法列表。我应该使用哪种算法来实现安全通信?
此外,由于可以指定要使用的安全提供程序,我应该使用哪个提供程序?
由于
答案 0 :(得分:27)
正如您在standard names documentation中所看到的,所有条目(SSLv3,TLSv1.0,TLSv1.1,...)都表示它们可能支持其他版本。
实际上,在Oracle JDK(和OpenJDK)中,他们都这样做。如果您查看source code,TLS10Context
类是用于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
的别名(SSL
和SSLv3
也是如此),{{1}协议。查看各种implementations of SSLContextImpl
(SSLContext
本身的内部类):
SSLContextImpl
(用于协议TLS10Context
,SSL
,SSLv3
,TLS
)默认情况下在客户端启用SSLv3到TLSv1.0。< / LI>
TLSv1
(用于协议TLS11Context
)默认情况下也会启用TLSv1.1。TLSv1.1
(用于协议TLS12Context
)默认情况下也会启用TLSv1.2。这在Java 8中与the new jdk.tls.client.protocols
系统属性一起发生了变化。
同样,在查看the source code for sun.security.ssl.SunJSSE
in OpenJDK 8u40-b25时,TLSv1.2
协议SSLContext
,TLSv1
和TLSv1.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会话。