如何解决 java 6 ssl 错误
How to workaround java 6 ssl error
我被困在 Java 6 环境中。我无法修改 JRE 配置。我正在尝试访问这样的特定服务:new RestTemplate().postForObject("https://someService.com","hello", String.class);
我收到这个错误java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024
可能是因为服务提供的参数大于 1024。我该如何解决这个问题?
我无法控制我尝试访问的服务。我不能接受基于服务器的解决方案。
来自http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh
Beginning with version 2.4.7, mod_ssl will use DH parameters which
include primes with lengths of more than 1024 bits. Java 7 and earlier
limit their support for DH prime sizes to a maximum of 1024 bits,
however.
If your Java-based client aborts with exceptions such as
java.lang.RuntimeException: Could not generate DH keypair and
java.security.InvalidAlgorithmParameterException: Prime size must be
multiple of 64, and can only range from 512 to 1024 (inclusive), and
httpd logs tlsv1 alert internal error (SSL alert number 80) (at
LogLevel info or higher), you can either rearrange mod_ssl's cipher
list with SSLCipherSuite (possibly in conjunction with
SSLHonorCipherOrder), or you can use custom DH parameters with a
1024-bit prime, which will always have precedence over any of the
built-in DH parameters.
一些选项,取决于您未指定的一些详细信息:
如果您可以更改客户端上的代码,并且服务器接受纯 RSA 密钥交换,即不接受 DHE 或 ECDHE,因此没有当今许多人要求的前向保密性,请将客户端更改为禁用所有名称包含 _DHE_
的密码套件。 (为了安全起见,也禁用 _DH_
静态套件,尽管几乎没有人使用它们,而且您的服务器也不太可能使用它们。)
如果 RestTemplate
(或它称为您控制的东西)直接创建 SSL 套接字并对其执行 HTTP,在该创建调用 .getEnabledCipherSuites()
获取当前数组,创建一个新数组排除不需要的项目,.setEnabledCipherSuites()
.
如果它在 https:
URL 上使用 URLConnection
,创建一个包装标准的 SSLSocketFactory
并如上所述修改(创建的)套接字,并制作该工厂是 HttpsURLConnection
.
的默认工厂
如果它使用其他东西,比如 Apache httpclient,可能有等效的技术或设置,但我不知道。
如果您可以在客户端更改代码并添加库,并且服务器接受 ECDHE 密钥交换,请从 https://www.bouncycastle.org 获取 bcprov jar 并将其放在您的类路径中的某个位置,并在您的应用程序的开头执行 java.security.Security.addProvider ( new org.bouncycastle.jce.provider.BouncyCastleProvider () )
。这是有效的,因为 Java6 JSSE 支持 ECHDE 密码套件 如果 有一个 ECC 原语提供者, Java6 没有包括; Java7 为此添加 SunEC。 BC 提供了一大堆您通常不需要的东西,但其中包括 ECC 原语。
如果服务器接受 HTTP-no-S 并且您没问题,请使用 http:
。您可能仍然可以通过 运行 通过 SSH 隧道或 VPN 等来保护传输,具体取决于服务器。
如果您需要 HTTPS 并且可以在客户端(或通过物理安全 LAN 连接的计算机)安装软件,请从 https://www.stunnel.org 安装 stunnel 并将其配置为在本地侦听您选择的端口并使用 SSL 连接到真实服务器 name/address 和端口,并让您的(真实)客户端将 http-no-s 连接到 localhost 或 vernearhost 上的 stunnel 端口。 Stunnel 然后将此 HTTP 包装在 SSL/TLS 中使其成为 HTTPS。
注意前两个选项绕过 Java6(和 7,在 8 中固定)整数 Diffie-Hellman 密钥交换的限制,但它们不会将 Java6 限制更改为 TLSv1 .0 协议。使用超过 1024 位整数 DH 参数的服务器可能是因为它受到严格的安全要求(这可能是必要的,也可能不是必要的,但如果你不控制服务,你就无法决定),许多这样的安全要求今天阻碍了 TLSv1.0,并且很可能很快就会禁止它,在这种情况下 Java6 就完全不走运了。
而如果有安全需求,选项3也未必可以接受,只剩下4(stunnel)。
我被困在 Java 6 环境中。我无法修改 JRE 配置。我正在尝试访问这样的特定服务:new RestTemplate().postForObject("https://someService.com","hello", String.class);
我收到这个错误java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024
可能是因为服务提供的参数大于 1024。我该如何解决这个问题?
我无法控制我尝试访问的服务。我不能接受基于服务器的解决方案。
来自http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh
Beginning with version 2.4.7, mod_ssl will use DH parameters which include primes with lengths of more than 1024 bits. Java 7 and earlier limit their support for DH prime sizes to a maximum of 1024 bits, however.
If your Java-based client aborts with exceptions such as java.lang.RuntimeException: Could not generate DH keypair and java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive), and httpd logs tlsv1 alert internal error (SSL alert number 80) (at LogLevel info or higher), you can either rearrange mod_ssl's cipher list with SSLCipherSuite (possibly in conjunction with SSLHonorCipherOrder), or you can use custom DH parameters with a 1024-bit prime, which will always have precedence over any of the built-in DH parameters.
一些选项,取决于您未指定的一些详细信息:
如果您可以更改客户端上的代码,并且服务器接受纯 RSA 密钥交换,即不接受 DHE 或 ECDHE,因此没有当今许多人要求的前向保密性,请将客户端更改为禁用所有名称包含
_DHE_
的密码套件。 (为了安全起见,也禁用_DH_
静态套件,尽管几乎没有人使用它们,而且您的服务器也不太可能使用它们。)如果
RestTemplate
(或它称为您控制的东西)直接创建 SSL 套接字并对其执行 HTTP,在该创建调用.getEnabledCipherSuites()
获取当前数组,创建一个新数组排除不需要的项目,.setEnabledCipherSuites()
.如果它在
的默认工厂https:
URL 上使用URLConnection
,创建一个包装标准的SSLSocketFactory
并如上所述修改(创建的)套接字,并制作该工厂是HttpsURLConnection
.如果它使用其他东西,比如 Apache httpclient,可能有等效的技术或设置,但我不知道。
如果您可以在客户端更改代码并添加库,并且服务器接受 ECDHE 密钥交换,请从 https://www.bouncycastle.org 获取 bcprov jar 并将其放在您的类路径中的某个位置,并在您的应用程序的开头执行
java.security.Security.addProvider ( new org.bouncycastle.jce.provider.BouncyCastleProvider () )
。这是有效的,因为 Java6 JSSE 支持 ECHDE 密码套件 如果 有一个 ECC 原语提供者, Java6 没有包括; Java7 为此添加 SunEC。 BC 提供了一大堆您通常不需要的东西,但其中包括 ECC 原语。如果服务器接受 HTTP-no-S 并且您没问题,请使用
http:
。您可能仍然可以通过 运行 通过 SSH 隧道或 VPN 等来保护传输,具体取决于服务器。如果您需要 HTTPS 并且可以在客户端(或通过物理安全 LAN 连接的计算机)安装软件,请从 https://www.stunnel.org 安装 stunnel 并将其配置为在本地侦听您选择的端口并使用 SSL 连接到真实服务器 name/address 和端口,并让您的(真实)客户端将 http-no-s 连接到 localhost 或 vernearhost 上的 stunnel 端口。 Stunnel 然后将此 HTTP 包装在 SSL/TLS 中使其成为 HTTPS。
注意前两个选项绕过 Java6(和 7,在 8 中固定)整数 Diffie-Hellman 密钥交换的限制,但它们不会将 Java6 限制更改为 TLSv1 .0 协议。使用超过 1024 位整数 DH 参数的服务器可能是因为它受到严格的安全要求(这可能是必要的,也可能不是必要的,但如果你不控制服务,你就无法决定),许多这样的安全要求今天阻碍了 TLSv1.0,并且很可能很快就会禁止它,在这种情况下 Java6 就完全不走运了。 而如果有安全需求,选项3也未必可以接受,只剩下4(stunnel)。