SSLHandshakeException - 使用自签名证书从 Web 应用程序调用 Web 服务

Posted

技术标签:

【中文标题】SSLHandshakeException - 使用自签名证书从 Web 应用程序调用 Web 服务【英文标题】:SSLHandshakeException - Calling webservice from web application using self signed certificate 【发布时间】:2019-06-30 22:17:00 【问题描述】:

我的 Web 应用程序和 Web 服务在同一个 tomcat 容器中运行。如果我不使用 HTTPS,一切正常。 当我在 HTTPS 上同时运行 Web 应用程序和 Web 服务时,当 Web 应用程序尝试调用 Web 服务时,我会收到 SSLHandshakeException。

案例 1

我使用以下命令创建了一个本地自签名证书文件

%JAVA_HOME%\bin\keytool -genkeypair -alias test1 -keyalg RSA -keystore c:/apps/test1.crt

一个名为test1.crt 的证书文件已在文件夹C:\apps 中创建。

现在,我想在 Java 密钥库中导入此证书,使用以下命令

%JAVA_HOME%\bin\keytool -import -alias test1 -file c:/apps/test1.crt-keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit

我遇到错误 -

密钥工具错误:java.lang.Exception:条目不是 X.509 证书

当我在 Tomcat 中使用此证书文件时,设置如下

<Connector port="8443"
    maxHttpHeaderSize="8192"
    maxThreads="150"
    minSpareThreads="25"
    maxSpareThreads="75"
    enableLookups="false"
    disableUploadTimeout="true"
    acceptCount="100"
    scheme="https"
    secure="true"
    clientAuth="false"
    sslProtocol="TLS"
    SSLEnabled="true"
    URIEncoding="UTF-8" 
    keystorePass="changeit" 
    keystoreFile="C:/apps/test2.crt" />

我在服务器启动时没有收到任何错误。当我从应用程序调用 web 服务时,我收到 SSLHandshakeException

案例 2

我在 Java 密钥库中添加了一个本地自签名证书,使用以下命令

%JAVA_HOME%/bin/keytool -genkeypair -alias test2 -keyalg RSA -validity 1000 -keysize 2048 -keystore %JAVA_HOME%/jre/lib/security/cacerts

已添加证书,我已使用以下命令验证了该证书

JAVA_HOME%\bin\keytool -list -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit

现在,我已经从 Java 密钥库中导出了一个证书文件,使用以下命令

%JAVA_HOME%/bin/keytool -export -alias test2 -keystore %JAVA_HOME%/jre/lib/security/cacerts -rfc -file C:/apps/test2.crt

一个名为test2.crt 的证书文件已在文件夹C:\apps 中创建。

当我在 Tomcat 中使用此证书文件时,设置如下

<Connector port="8443"
    maxHttpHeaderSize="8192"
    maxThreads="150"
    minSpareThreads="25"
    maxSpareThreads="75"
    enableLookups="false"
    disableUploadTimeout="true"
    acceptCount="100"
    scheme="https"
    secure="true"
    clientAuth="false"
    sslProtocol="TLS"
    SSLEnabled="true"
    URIEncoding="UTF-8" 
    keystorePass="changeit" 
    keystoreFile="C:/apps/test2.crt" />

我收到以下错误

在 org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:491) 原因:java.lang.IllegalArgumentException:无效的密钥库格式 在 org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114) 在 org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:85) 在 org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:224) 在 org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1044) 在 org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:540) 在 org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74) 在 org.apache.catalina.connector.Connector.initInternal(Connector.java:932) ... 13 更多

原因:java.io.IOException:无效的密钥库格式 在 sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:663) 在 sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56) 在 sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224) 在 sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70) 在 java.security.KeyStore.load(KeyStore.java:1445) 在 org.apache.tomcat.util.net.SSLUtilBase.getStore(SSLUtilBase.java:160)

虽然服务器已启动并且我可以使用我的应用程序。但是当我尝试调用网络服务时,我得到了

这是SSLHandshakeException的日志

嵌套异常是: javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径

错误: (org.apache.axis.AxisFault) --> [;嵌套异常是: javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径]

AxisFault 故障代码:http://schemas.xmlsoap.org/soap/envelope/Server.userException 故障子代码: faultString:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径 故障演员: 故障节点: 故障详情: http://xml.apache.org/axis/stackTrace:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径

【问题讨论】:

【参考方案1】:

我认为对于 Tomcat,keystoreFile 是“%JAVA_HOME%/jre/lib/security/cacerts”,而您不必指明任何密钥库,因为您向 jre 通用密钥库添加了密钥对,但使用起来完全不正确"C:/apps/test2.crt"。

同时尝试将服务器证书添加到信任库文件:

 JAVA_HOME%\bin\keytool -import -v -trustcacerts -alias test2 -file C:/apps/test2.crt -keystore  %JAVA_HOME%/jre/lib/security/cacerts -keypass changeit -storepass changeit

【讨论】:

以上是关于SSLHandshakeException - 使用自签名证书从 Web 应用程序调用 Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

文件下载 SSLHandshakeException

SSLHandshakeException 无法验证用户身份

SSLHandshakeException:不存在主题替代名称

服务帐户引发 - SSLHandshakeException

Jmeter中的SSLHandshakeException错误

SSLHandshakeException:握手期间远程主机关闭连接