最近,我们的组织将其中一个 Java 应用程序代码从 Java 8 迁移到 Java 11。现在,我们的应用程序面临一个独特的问题。 我们的 tomcat 服务器遇到了一个奇怪的问题,它无法向第 3 方服务器提供其自签名 ECDSA 证书(作为 mTLS SSL 协商的一部分请求)失败并出现以下错误。
Error while invoking external url error: Client exception while GET:javax.net.ssl.SSLException: org.bouncycastle.tls.TlsFatalAlertReceived: handshake_failure(40)","error-type":"java.lang.Exception","error-message":"Client exception while GET:javax.net.ssl.SSLException: org.bouncycastle.tls.TlsFatalAlertReceived: handshake_failure(40)","error-stack-trace":"java.lang.Exception: Client exception while GET:javax.net.ssl.SSLException: org.bouncycastle.tls.TlsFatalAlertReceived: handshake_failure(40)
我的组织使用 BC-FIPS 提供商,不支持
-Djavax.net.debug
调试参数。
我确实捕获了 tcpdump,这表明我的应用程序没有提供用于 SSL 协商的有效证书。 (下面的快照中证书长度为0)
客户端和服务器 ECDSA 证书均已正确交换且有效。 在这种情况下,服务器能够协商入站基于 ECDSA 的 SSL 请求(ECDSA 密码),不会出现任何问题。此外,如果证书类型是 RSA,相同的代码绝对可以正常工作。
我们使用与 Java8 中使用的相同的 trustStore; trustStore 中没有任何更改,并且存储是像以前一样使用 Java8
keytool
命令生成的。
我们使用 bc-fips-1.0.2.3.jar,并且所有依赖库(例如 bcpkix-fips.jar、bctls-fips.jar)都已添加。我们在这里没有做任何更改,从 Java8 到 Java11。
唯一的重大变化是运行时从 jre8 更改为 jre 11。
任何有关调试或如何推进的指示都值得赞赏。
trustStore 格式为 BCFKS。
谢谢, 布林尔
问题出在 java.security 文件中的
ssl.KeyManagerFactory.algorithm
属性。该值设置为 SunX509
,将值更改为 PKIX
就可以了。