为什么 Java 运行时在 SSL 信任库的工作方式以及我们如何处理它方面有如此大的不同?

Why does Java runtime differ so much in how SSL trust store works and how do we deal with it?

我们碰巧 运行 REST API Web 服务公开了 http:// 和 https:// 端点。 https:// 端点后面有一个 SSL 证书,需要不时更新一次。每隔一段时间我们更新 SSL 证书时,一些用户 运行 宁 Java 与我们的服务交互的程序抱怨他的程序不再工作并且他必须更改 Java 证书信任库中的某些内容.我们有使用任何语言开发的程序的用户 - PHP、C#、Ruby,无论其他什么 - 当我们更改证书时,他们中的 none 曾经抱怨过,但一些 Java 用户有每隔一段时间就会出问题。

Java 运行时间在这方面有何特殊之处?提升用户体验应该怎么做?

We have users with programs developed in anything - PHP, C#, Ruby, whatever else - and none of them ever complain when we change the certificate yet some Java users have problems every other time.

  • PHP:直到最近 PHP 根本没有默认验证证书。这只是 changed with PHP 5.6。如果它验证它使用 UNIX 上通常具有所需 CA 的系统 CA 存储。因此,可能是您的 PHP 客户端根本不验证证书,因此没有问题。
  • C# - 使用通常具有所需 CA 的系统 CA 存储
  • Ruby: 使用系统CA存储
  • Perl:要么根本不验证,要么使用系统 CA 存储,要么使用来自 mozilla 的 CA 存储,具体取决于模块的版本和您使用的发行版。

Java 而不是带有它自己的 CA 存储,其中包含的 CA 比通常随系统一起提供的少得多。而且它还取决于 Java 版本。因此,客户端使用的 Java 版本可能不知道您使用的根 CA。此外,较旧的 Java 版本不支持 SNI。他们有弱 DH 密钥的问题,不支持更大的 RSA 密钥等。由于有很多旧的和不受支持的 Java 安装,所以选择影响您今天的应用程序的问题。