java 1.6 TLS1.2 support using proxy nginx/squid解决问题

java 1.6 TLS1.2 support using proxy nginx/ squid solution issues

我有一个遗留的 java Web 应用程序可以调用外部 Web 服务。该服务的提供商正在关闭 TLS1.0 支持。因此,我正在尝试查看该应用程序如何继续使用该服务。

我看到的选项是 a) 使用 BouncyCastle JCE 而不是 Java JCE http://boredwookie.net/index.php/blog/how-to-use-bouncy-castle-lightweight-api-s-tlsclient/, which I guess requires code change/ recompile (we don't have the luxury of doing it) or 2) use proxy servers https://www.reddit.com/r/sysadmin/comments/48gzbi/proxy_solution_to_bump_tls_10_connection_to_tls_12/

我已经尝试过 nginx 代理 - 它似乎无法处理终端服务器期望的 TLS1.0 传入和 TLS1.2 之间的切换。

 server { listen 443 ssl; server_name proxy.mydomain.com;

ssl_certificate D:/apps/openssl/proxy.mydomain.com.cert; ssl_certificate_key D:/apps/openssl/proxy.mydomain.com.private; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3- SHA:!KRB5-DES-CBC3-SHA:!SRP; ssl_prefer_server_ciphers 上;

位置/{ proxy_pass https://fancyssl.hboeck.de/; }

由于 https://fancyssl.hboeck.de only support TLS1.2 but works with https://www.google.com 支持 TLS1.0,因此出现 502/错误网关错误。

我在 Windows 上做这个。

不是TLSv1.2,是缺少SNI导致重新协商。

首先,我使用与您类似的配置设置了 nginx (1.8.1/Windows),除了使用我自己的密钥和证书并代理到我自己的测试服务器。它工作正常,从使用 TLSv1.0 的 Java6 请求者连接到使用 TLSv1.2 的服务器(甚至是 'best' 密码套件之一的 ECDHE-RSA-AES256GCM-SHA384)并返回页面正常。我试了 fancyssl.hboek.de 和你一样得到了 502。

使用 wireshark 我看到 nginx 不发送 SNI(默认情况下)并且至少使用 IPv4 地址 46.4.40.249(我没有 IPv6)该服务器显然托管多个域,因为没有 SNI 它提供一个不同的(并且已过期!)证书,用于 *.schokokeks.org,并且在第一个应用程序数据(请求)之后它发送一个加密的握手(一个重新协商请求——nginx 不接受)。使用 openssl s_client 进行测试确认具有 SNI 的服务器会立即发送页面,但没有它会先重新协商;将 nginx 重新指向 openssl s_server 确认如果服务器请求重新协商,没有收到响应,并且关闭 nginx 将其视为 502.

我猜想 Apache 正在重新协商,因为它意识到所请求的主机不在证书的范围内——除了它再次使用 'wrong' 证书。我没有尝试追踪那部分。

Google 在我连接时支持 TLSv1.2(和 ECDHE-RSA-AESGCM),但即使没有 SNI 也不会重新协商,大概是因为它是这样的www.google.com 服务器上没有其他任何东西运行并且没有歧义。我的测试服务器没有虚拟主机,所以不需要 SNI。

The nginx documentation reveals a directive proxy_ssl_server_name 可以设置on启用SNI,然后代理到这个服务器就可以了。

仅供参考:该网页上的一些陈述是错误的,尽管它的结论(如果可能,将 TLSv1.2 与 ECDHE 或 DHE 和 AES-GCM 一起使用)是好的。 此外,您的 ssl_ciphers 字符串大部分都没用,但您没有问过。


ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP

HIGH 是一个很好的开始。

SEED 在(仅)由 Java/JSSE 客户端使用的服务器中没有用,因为它没有在 Java 端实现。即使在 Java 之外,它也几乎只在韩国使用,在那里它被创建为 DES 或 IDEA 的替代品,即使在那里它也大部分被 ARIA 淘汰,ARIA 是 AES 的替代品——但不是由 OpenSSL 和 nginx 实现。

aNULL 可能是不需要的,因为 JSSE 默认禁用 'anonymous' 套件,但在这里作为纵深防御是值得的。

!eNULL 什么都不做; HIGHDEFAULT 甚至 ALL 中都没有 eNULL 套件。您只能明确地或使用奇怪的 COMPLEMENTOFALL 来获取它们——您不应该这样做。

!EXPORT !DES !RC4什么都不做; none 个在 HIGH 中。相反,如果您在旧版本的 OpenSSL 上从 DEFAULT 开始,或者从 ALL 开始,那么它们会很好。

!PSK 不需要; nginx 似乎没有为 PSK 配置,JSSE 也没有实现它。

!RSAPSK 被忽略,因为 OpenSSL 没有实现该密钥交换,如果实现了,那些套件已经包含在上面。

!aDH !aECDH!aNULL 覆盖,因此什么都不做。

!EDH-DSS-DES-CBC3-SHA 很傻;当您保留其他 DHE_DSS 和 3DES 套件时,没有理由排除这个套件。

!KRB5-DES-CBC3-SHA 被忽略,因为 OpenSSL 没有实现 Kerberos,如果它实现了,则不会为它配置 nginx 再加上在保持类似的情况下排除一个套件是愚蠢的。

!SRP 不需要;像 PSK nginx 显然没有配置和 JSSE 没有实现。

因此:HIGH:!aNULL 就是您所需要的。