java - HTTPS:如何支持所有SSL/TLS协议(protocol)和密码套件?

标签 java ssl https java-8 httpurlconnection

我正在研究需要对各种服务器发出HTTPS请求的搜寻器。因此,我希望我的搜寻器支持所有可能的协议/密码。

我目前正在使用Java 8,但愿意进行升级(不要紧)。

我创建了SSLContext,如下所示:

SSLContext sslContext = SSLContext.getInstance("TLSv1.2");


我猜每个支持TLSv1.3的服务器也都支持1.2。

这将向后兼容吗?即支持TLS 1.1 / 1.0和SSL?

(如今,甚至还使用SSL吗?)

为了保证成功进行SSL / TLS握手,我还需要做什么?

谢谢!

最佳答案

因此,我希望我的搜寻器支持所有可能的协议/密码。
  我目前正在使用Java 8,但愿意进行升级(不要紧)。
  
  我猜每个支持TLSv1.3的服务器也都支持1.2。
  这将向后兼容吗?即支持TLS 1.1 / 1.0和SSL?
  (如今,甚至还使用SSL吗?)


是的,至少在不久的将来,几乎所有支持1.3的人也将支持1.2,除了一些专门测试1.3兼容性的站点。 (我敢打赌,很多人甚至会继续支持1.1,例如PCI仍然勉强允许它,但您并不需要它;任何支持1.1的Java也支持1.2。)TLSv1.2上下文支持较低版本(如果允许) ,请参见下文),默认的TLS上下文在j8中也支持1.2和更低版本(j7中的默认不支持1.1和1.2客户端)。

没有人应该使用SSLv3 since 2016 at latest和Java版本,因为2014-12中的j8u31已配置为禁止它,尽管如果您更改配置以允许它,该代码仍然存在。有关j8的信息,请参见jdk.tls.disabledAlgorithms中的JRE/lib/security/java.security条目;有关j9的信息,请参见JAVA/conf/security/java.security条目。注意,只有通过在启动时更改配置或安全属性,才能通过调用SSLSocket.setEnabledProtocols和相关方法的代码来逆转这种“禁用”状态;相反,只要需要,就可以启用通过上下文选择“禁用”的协议,反之亦然。

自世纪之交以来,没有人应该使用SSLv2(无论是2000还是2001,这取决于您的学究;在这种情况下,区别并不重要)。 Java不会(也从来没有)实现它。

目前可以使用TLSv1.0。从理论上讲,它很容易受到BEAST的攻击,但是事实证明,这毕竟不是什么危险,现在,通过对应用程序数据进行1 / n拆分可以进一步缓解这种情况。由于Java默认包含它,因此我不会费心删除它,但是您可能会对在实际选择它的任何服务器上保持警惕。

您不能支持所有密码套件,因为Java不能全部实现。幸运的是您不需要。 Internet上没有人使用PSK(1.3中的恢复变体除外)SRP或Kerberos。 Java仅实现最后一个。可能几乎没有或很少需要Camellia SEED ARIA IDEA或AES-CCM,但Java都没有实现(至少在标准的密码提供程序中),尽管如果提供的话,您可能会遇到至少支持其中一些功能的Java。没有人应该支持RC4,“导出”套件,“ eNULL”和单DES。 Java版本再次禁止java.security中的RC4,因为
2015年8月8u60,默认情况下禁用了很长一段时间的其他功能,以及“匿名”套件(又名“ aNULL”)。最后那是我要考虑改变的唯一一个。我可以想象罕见但合理的情况,即在没有证书身份验证的情况下运行公共服务器,但在其他方面却是安全的。

但是除了协议和密码以外,还有其他安全参数可以阻止连接。特别是,现在Java已配置为使用太短而不能保证安全的密钥或参数来拒绝握手,或者使用MD5签名的证书拒绝为此目的而中断,即使这些证书在两个端点都可接受的密码套件中使用。这些设置在disabledAlgorithms中与证书的设置在jdk.certpath.disabledAlgorithms中相似,您可能需要放宽它们。使用弱化参数的连接可能会受到威胁,但是由于您大概没有任何敏感信息要发送到未知服务器,并且无论如何也不会信任您从它们接收到的任何信息,因此这种妥协可能不会一个问题。

接下来,可能最大的是证书验证。您将在许多站点中使用实际上无效的证书,并且有许多站点无法通过标准Java信任库JRE/lib/security/cacerts或类似Windows或Mozilla的证书进行验证。由于您可能不在乎是从真实服务器还是从合法服务器获取数据,因此可以使用非默认TrustManager忽略证书错误,该证书仅返回成功,而无需实际验证服务器的证书链。如果在SO上搜索其他Q,您可能会发现一百个有人建议通过“只需剪切并粘贴此TrustManager来解决所有问题而无需任何思考,理解或努力”的情况下,建议在Java中“解决” TLS或https问题。在许多情况下,这是由实际上并不了解TLS的人员提出的,这些问题最初不是针对证书问题的,因此“解决方案”无济于事,只会在以下情况下使系统完全不安全:实际问题已解决。我认为您的问题是我所见过的第一个问题,该解决方案实际上是合适的。

最后,TLS中有一个名义上可选的功能,即服务器名称指示(SNI),许多服务器现在都需要这些功能,尤其是CDN,WAF,IDS / IPS以及处理多个域流量的类似内容。根据用于建立连接的API和选项的不同,较早版本的Java并不总是发送SNI。但是,除非故意禁用它,否则最近的j8及更高版本应该这样做–可能会发现确实需要禁用它的某些损坏的服务器like this recent Q

关于java - HTTPS:如何支持所有SSL/TLS协议(protocol)和密码套件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56246393/

相关文章:

go - go是否实现自己的ssl库?

php - 如何在 PHP 中手动解析 HTTP(S) 连接中的主机

javascript - 如何为在 Express 中运行的应用程序配置 SSL 证书?

Java EE - 无法通过 IntelliJ 上的 JDBC 连接到数据库

java - 在 Web pojo 类中使用 ejb session 时获取 null

java - 应该使用哪个类在 java 中创建 TLS 连接。套接字类或 SSLSocket 类?

react-native - 我是否将 ATS 与 React Native Firebase 一起使用?

java - 无法在 super 账本结构中调用链码

java - 如何在Java中计算多位数字中奇数、偶数和零的个数?

security - 中间根权限跨链验证