Java 6支持ECDHE加密套件

4
Java 6中的Java加密架构标准算法名称文档列出了ECDHE密码套件。因此,我希望它们在Java 6中得到支持。然而,OOTB Java 6和JCE无限强度策略文件的添加都不能使它们起作用。
书籍Bulletproof SSL and TLS也表明Java 6支持ECDHE,但有一个警告:

在服务器上启用并优先使用ECDHE密码套件。Java 6和7客户端支持这些套件,并会愉快地使用它们。(但是请注意,对于Java 6,您必须切换到使用v3握手协议以在客户端级别使用ECDHE密码套件。)

我假设作者所说的v3握手协议是SSLv3?虽然我没有尝试过,但即使这样也不是一种可行的选项,因为存在POODLE漏洞。
那么我错过了什么呢?

你是如何测试它的?有任何示例代码吗?如果连接到服务器,它是否支持ECDHE? - Khanna111
是的,服务器确实支持ECDHE。当我使用Java 7时,初始客户端hello会传递多种ECDHE密码套件,而服务器会返回TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA。暂无示例代码,我可能会在将来提供。 - chashi
那么在服务器hello之后会出现什么异常?有任何警报吗? - Khanna111
我遇到了“素数大小必须是 64 的倍数,且只能在 512 到 1024(含)范围内”的异常,但这只是因为服务器返回给我的是一个基于 DHE(非 ECHDE)的密码套件,其素数对于 Java 6 来说太大了。这就是为什么我想在 Java 6 中启用 ECDHE,从而使服务器返回相应的密码套件。 - chashi
4个回答

9
Java 1.6及更高版本中的SSL/TLS实现“JSSE”支持ECDHE套件,如果有需要ECC基元的可用(JCE)提供程序Java 1.6 OOTB不包含这样的ECC提供程序,但可以添加一个Java 7和8都包括SunECC提供程序。这似乎是今天的热门话题,请参见https://security.stackexchange.com/questions/74270/which-forward-secrecy-cipher-suites-are-supported-for-tls1-0-protocolshttps://superuser.com/questions/848698/testing-cipher-suite-using-openssl-for-tomcat-server-is-resulting-in-wrong-manne (出乎意料地被迁移到安全性)。
Ristic的书无疑指的是v3格式的ClientHello。SSL2和SSL3之间存在重大格式变化,SSL2的ClientHello无法表示ECC的数据(特别是扩展数据)。所有版本的TLS(截至目前)都使用与SSL3相同的格式,但内容具有不同的重要性。在早期,SSL客户端通常使用SSL2格式的ClientHello,但包含升级到SSL3甚至TLS1.0的内容,以便成功地与所有服务器进行通信,因为许多SSL2仍在使用。
Java 1.6客户端大约在2006年时是过渡性的--默认情况下,它使用SSL2格式,并指定版本高达TLS1.0,但如果服务器同意使用SSL2而不是更高版本,则客户端会中止并抛出异常,表明"SSL2不安全"。这由伪协议字符串SSLv2Hello控制,因此在Java 1.6客户端上,您应该使用.setEnabledProtocols来删除/排除它。
Java 7和8仍然实现了SSLv2Hello,但不再默认启用,因此默认情况下使用v3格式,或者只要指定协议为(全部)SSL3或更好。7和8还实现了TLS1.1和1.2,而6没有,尽管只有8在客户端上默认启用它们。如果您连接到古老的SSL2-only服务器,则应仅指定SSLv2Hello - 当然,您应该尽力避免这样做。

4
dave_thompson_085提供的答案是正确的并且对我有帮助,但我想添加一些说明。正如他所说,可用的算法取决于JCE提供程序。我在Centos 5.4上使用Sun/Oracle Java 6 release 45,它没有ECDHE OOTB支持。
因此,我需要添加一个额外的JCE提供程序,Bouncy Castle(bouncycastle.org)是其中之一。按照这里的说明进行操作 https://www.bouncycastle.org/specifications.html#install。这将扩展支持到例如TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA。
另一种选择是使用Hotspot JRE捆绑的sun.security.pkcs11.SunPKCS11提供程序。您需要一个${java.home}/lib/security/nss.cfg文件,并包含以下内容:
name = NSS
nssDbMode = noDb
attributes = compatibility

这将利用libnss3,该库可能通过本地操作系统库提供必要的算法。已在Ubuntu 12.04上验证,但也可能适用于其他发行版。它在Centos 5.4上不起作用,因为RH/Centos 5被认为具有有限的椭圆曲线支持。

基于NSS的提议解决方案在TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384密码套件上无法工作,但BouncyCastle的解决方案可以。 - rodvlopes

1

您需要开启-Djavax.net.debug=all并查看发生了什么,并提供示例代码和日志。

在1.6中,SunJSSE支持TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider

因此,您应该使用它作为启用的协议设置您的SSLContext。请参阅http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#SSLContext获取详细信息。您还需要交换已启用的协议,以便启用1.2并处于领先地位。

另请参见


0

根据Chisther B.的答案,这是我遵循的步骤,使Java 1.6与ECDHE配合使用。

下载BouncyCastller (bcprov-jdk15to18-169.jar),将其复制到$JAVA_HOME/jre/lib/ext并在$JAVA_HOME/jre/lib/security/java.security中添加以下配置:

security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider

使用 Oracle JDK_1.6_211 测试了 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 和 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 密码套件。

我的 Dockerfile

COPY bcprov-jdk15to18-169.jar $JAVA_HOME/jre/lib/ext/
COPY java.security.bc.patch ./                                                                                                                                            
RUN patch $JAVA_HOME/jre/lib/security/java.security < java.security.bc.patch

java.security.bc.patch 内容

53a54
> security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接