更新:找到解决方案后,我编辑了问题以使其更清晰以供将来引用。
我从一家公司获得了公司(即不为人知的)CA 证书,该公司为我们提供了可从 Java 调用的 Web 服务。我将此 CA 证书添加到默认的 cacerts 信任存储区 (keytool -import -file cert.cer -alias myca -keystore jre/lib/security/cacerts
),但与服务的连接仍然失败并出现可怕的错误“PKIX 路径构建失败”消息。我已经检查过终端服务器证书的颁发者字段与 CA 证书中的相同,并且有效期也没有问题。
我不知道怎么解释。我可以想到以下原因,但我不知道哪个是正确的:
- 我注意到,当我将终端服务器证书也添加到信任库时,连接正常。也许 cacerts 的设计并不像我预期的那样工作(即所有由授权机构签署的证书都被认为是有效的),但我必须将所有终端服务器证书添加到信任库中,包括其颁发者的 CA 证书。
- 我必须以其他方式添加 CA 证书 - 通过不同的命令,添加到不同的文件等。
- 可能 CA 证书不正确,keytool 拒绝将其视为证书颁发机构。
- 可能由于其他原因 PKIX 路径构建失败。
如何调试这个问题才能找到答案?
详细信息:
- 终端服务器证书为通配符证书
- 没有中间证书,只有根证书和结束证书
最佳答案
我在使用 Let's Encrypt 签名证书时遇到了“PKIX 路径构建失败”的相同问题,当时 Java 没有将 Let's encrypt CA 证书合并到其默认信任库中。
最后,我能够通过在我的应用程序中嵌入仅包含根 CA 证书(和备份证书)的内部信任库来使 Java 信任“链的末端”服务器证书。
与在主 Java 信任库中导入证书相比,我更喜欢创建内部应用程序信任库,原因有两个:
- 您不需要在安装过程中执行其他额外步骤来初始化全局信任库
- 您将“信任”限制在您的应用程序中并且不影响在同一 JVM 上运行的其他应用程序(或者更好的是,如果需要,您甚至可以将信任限制在您应用程序中客户端对象的某些实例)
也许我遇到的情况与您面临的情况不同,所以如果我不明白这一点,请给我投反对票。
关于java - 如何将 CA 证书添加到 cacerts 存储以便它按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46529633/