Spring boot 证书握手有时成功,有时失败。这是非常不一致的

Spring boot 证书握手有时成功,有时失败。这是非常不一致的,spring-boot,ssl-certificate,x509certificate,Spring Boot,Ssl Certificate,X509certificate,我看到了一个非常奇怪的问题。在我的spring boot应用程序中,我通过从浏览器导出.cer文件并以编程方式加载来通过https调用外部服务。我在springboot加载后立即调用了外部证书。一旦启动应用程序,我将在50%的时间内得到以下错误,在应用程序正确启动的剩余50%时间内得到以下错误 sun.security.validator.ValidatorException:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilder

我看到了一个非常奇怪的问题。在我的spring boot应用程序中,我通过从浏览器导出.cer文件并以编程方式加载来通过https调用外部服务。我在springboot加载后立即调用了外部证书。一旦启动应用程序,我将在50%的时间内得到以下错误,在应用程序正确启动的剩余50%时间内得到以下错误

sun.security.validator.ValidatorException:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:找不到请求目标的有效证书路径 javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:找不到请求目标的有效证书路径

我正在使用URLConnection调用外部服务。使用conn.setsslssocketfactory()创建SSLContext并将其添加到URLConnection

最后用下面的代码点击服务

outputStream = conn.getOutputStream();
outputStream.write(requestBodyMsg.getBytes());
outputStream.flush();
相同的服务呼叫的成功率为50%。一旦它失败,如果我重新启动服务器,它是成功的

当我在较低的环境中100%命中相同的服务时,相同的代码也可以工作。我比较了目标服务的较低和较高环境之间的网络连接中的密码。它们是一样的

邮递员控制台日志上的TLS信息为

授权错误:“无法验证叶子签名”
授权:false
密码:{…}
名称:“ECDHE-RSA-AES128-GCM-SHA256”
版本:“TLSv1/SSLv3”

任何帮助都将不胜感激


另一个有趣的观察结果是:如果我在调试模式下启动应用程序并一直按F6移动执行,那么握手在100%的时间内都是成功的。

获取工作场景和非工作场景的SSL调试日志,并检查失败的位置。请参考[1,2]获取SSL调试日志。[1]. 〔2〕这里讨论了类似的问题〔1〕〔1〕,每当我看到“时间50%的工作”时,我考虑不安全并发的可能性。但是,
loadTrustedStore()
中的所有对象似乎都是本地对象,除了证书文件。是否有可能在应用程序运行期间创建或更改该文件?正如@Senthuran所建议的,我启用了SSL调试。当它失败时,我看到下面的错误。另一方面,当它成功运行时,它会说“找到了受信任的证书”***%%无效:[Session-1,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]main,发送TLSv1.2警报:致命,描述=证书\u未知main,写入:TLSv1.2警报,长度=2 main,调用closeSocket()main,处理异常:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到valid@PresidentJamesK.Polk:证书在外部应用程序和我的应用程序上都不会更改。获取证书的SSL调试日志工作场景和非工作场景,并检查失败的地方。请参考[1,2]获取SSL调试日志。[1]. 〔2〕这里讨论了类似的问题〔1〕〔1〕,每当我看到“时间50%的工作”时,我考虑不安全并发的可能性。但是,
loadTrustedStore()
中的所有对象似乎都是本地对象,除了证书文件。是否有可能在应用程序运行期间创建或更改该文件?正如@Senthuran所建议的,我启用了SSL调试。当它失败时,我看到下面的错误。另一方面,当它成功运行时,它会说“找到了受信任的证书”***%%无效:[Session-1,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]main,发送TLSv1.2警报:致命,描述=证书\u未知main,写入:TLSv1.2警报,长度=2 main,调用closeSocket()main,处理异常:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到valid@PresidentJamesK.Polk:证书在外部应用程序和我的应用程序上都不会更改。
outputStream = conn.getOutputStream();
outputStream.write(requestBodyMsg.getBytes());
outputStream.flush();