我有一个spring boot应用程序,其中我尝试使用HTTPS SOAP webservice,这需要使用私钥进行身份验证,这是我的keystore.jks的一部分,作为别名client
我有一个带有以下配置的弹簧启动应用程序
server:
port: 8443
sessionTimeout: 30
ssl:
key-store: keystore.jks
key-store-password: 123456
keyAlias: tomcat
key-password: 123456
keyPassword: 123456
trust-store: truststore.jks
trust-store-password: 123456
keystore.jks
有两个别名(PFX)tomcat
,用于托管服务,client
用于通过SOAP
网络服务进行身份验证
我在尝试调用java soap client stub
时看到以下异常%% Invalidated: [Session-2, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256]
https-jsse-nio-443-exec-4, SEND TLSv1.2 ALERT: fatal, description = certificate_unknown
https-jsse-nio-443-exec-4, WRITE: TLSv1.2 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 03 00 02 02 2E .......
https-jsse-nio-443-exec-4, called closeSocket()
https-jsse-nio-443-exec-4, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
2017-04-18 17:15:26.253 ERROR 2360 --- [-nio-443-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://tseiod-test.trustweaver.com/ts/svs.asmx?wsdl. It failed with:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.] with root cause
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at java.net.URL.openStream(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
at javax.xml.ws.Service.<init>(Unknown Source)
来自client
的{{1}}别名似乎未用于使用HTTPS网络服务进行身份验证,无论如何我可以强制Spring引导使用来自keystore.jks
的特定别名吗?或者有任何解决方法来实现这一目标吗?
答案 0 :(得分:1)
尝试使用此代码创建不验证证书链的信任管理器。 希望这是解决您问题的方法。
SSLTool.java
import javax.net.ssl.*;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
public class SSLTool {
public static void disableCertificateValidation() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}};
// Ignore differences between given hostname and certificate hostname
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);
} catch (Exception e) {}
}
}
并在使用HTTPS SOAP Web服务之前调用该方法。
new SSLTool();
SSLTool.disableCertificateValidation();