/C=US/ST=CA/O=SonicWALL Inc./CN=SonicWALL 防火墙 DPI-SSL
您的流量明显被深度数据包检测防火墙拦截,该防火墙充当 MITM 代理来监控您的流量。
这通常可以被认为是“合法的”MITM 攻击者。 (无论这是否合法,这可能取决于许多法律和道德方面。)您的本地网络管理员应该能够告诉您一些有关这方面的信息。如果这是公司网络的一部分,则该公司正在监视您的流量,包括您的 HTTPS 连接的内容(因此端到端不再安全)。如果防火墙正常工作,它仍然应该保护从防火墙到服务器的连接(可能很难知道它是否正确检查证书。)
一般来说,这样的防火墙或代理充当自己的证书颁发机构,有效地根据请求伪造每个证书。
公司网络上的大多数客户端都会信任它颁发的证书(就像您面临的那样),因为系统管理员还会将 CA 证书作为受信任的证书安装到该网络中的每台计算机中。您可能拥有操作系统受信任的根证书。
但是,网络管理员很可能没有将此 CA 证书安装到您的 JRE 安装中(默认情况下,它使用自己的一组信任锚)。
尝试从参考机器导出该 CA 证书(请参阅上面的名称)并将其导入您正在使用的信任库(您的 JRE 的默认信任库:cacerts 或您构建并传递给您的应用程序的新信任库通过javax.net.trustStore 属性)。
通常,您可以使用这样的东西(假设您已将防火墙的 CA 导出为“firewallca.pem”):
keytool -import -file firewallca.pem -alias firewallca -keystore truststore.jks
如果truststore.jks 文件不存在,它将被创建。否则,您可以在 JRE 的 lib/security 目录中获取 cacerts 文件的副本。您也可以直接在 cacerts 文件上执行此操作(使用 -keystore /path/to/truststore.jks,前提是您具有写入权限)。
如果您选择不在默认信任库(即 cacerts 文件)上执行此操作,而是使用像 truststore.jks 这样的本地信任库,则可以在运行应用程序时通过使用此系统属性来使用它:-Djavax.net.trustStore=/path/to/truststore.jks
有关配置信任库的其他方式,请查看this answer。
解决此问题的另一种方法是告诉 Java 使用 your OS's truststore。我假设您在这里使用的是 Windows。使用这些系统属性应该可以工作:
-Djavax.net.trustStore=NONE -Djavax.net.trustStoreType=WINDOWS-ROOT
(如果这不起作用,请尝试使用 WINDOWS-MY 而不是 WINDOWS-ROOT。)
WINDOWS-MY/WINDOWS-ROOT 有点错误,因为它会丢失 Windows 商店中的一些证书:它使用证书“友好名称”(非唯一)作为密钥库别名(唯一),所以具有给定友好名称的证书将隐藏具有相同名称的其他证书。 (不幸的是,这有效地减少了受信任的 CA 证书的数量。)
由于您所处的环境可能所有流量都通过您的 DPI 防火墙,因此您可能最多只需要使用一个 CA 证书。只要它在 Windows 列表中不与任何其他证书共享其“友好名称”,就可以了。