有一个服务器只发送它自己的证书,而不发送链中的任何颁发者(注意:它不是自签名的)。
当我在 Google Chrome 中连接到此服务器并查看证书时,我在"证书路径"选项卡中看到了完整链,但是当我尝试使用 Java 连接到此服务器并使用-Djavax.net.debug=SSL
时,我只能看到服务器自己的证书。
我注意到此证书上有一个名为"颁发机构信息访问"的扩展名,其中包含一个字段"备用名称",其中包含指向颁发者证书的 URL。我相信Chrome(或Windows可能)"知道"这个扩展,而Java没有"意识到",有没有办法在Java中使用它?(最好没有额外的类,但我意识到如果没有内置,可能没有简单的方法。
如果我只将根证书添加到 Java 的证书中,那么我将无法执行 TLS 握手(因为服务器只发送自己的证书,而根证书没有颁发它,中间人会)。此服务器不受我的控制,我无法让它发送中间证书。由于 Chrome 能够解析中间证书(我想是通过 AIA),我怀疑可能有一种方法可以在 Java 中做到这一点,而无需将中间证书添加到 cacerts 文件中,只有根证书,但我不知道如何让 Java 使用此 AIA 扩展来获取中间证书。
您需要设置相关的系统属性,以使 Java 应用程序能够下载根的中间证书。
System.setProperty("com.sun.security.enableAIAcaIssuers", "true");