java 尝试连接到 https Web 服务时“收到致命警报:handshake_failure”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16553420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"Received fatal alert: handshake_failure" when trying to connect to https web service
提问by Dave
I want to build a Spring 3 (v 3.1.1.RELEASE) application (on Java 1.6) to communicate with an HTTPS web service, which is using a self-signed certificate that I created. I'm confused about how to set up my truststores and keystones. Using my self-signed certificate, I generated a keystone using the below commands ...
我想构建一个 Spring 3 (v 3.1.1.RELEASE) 应用程序(在 Java 1.6 上)以与 HTTPS Web 服务通信,该服务使用我创建的自签名证书。我对如何设置我的信任库和基石感到困惑。使用我的自签名证书,我使用以下命令生成了一个 keystone ...
openssl pkcs12 -export -in server.crt -inkey server.key \
-out server.p12 -name myalias
keytool -importkeystore -deststorepass password -destkeypass password -deststoretype jks -destkeystore server.keystore -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass password -alias myalias
Then I configured my Spring application like so …
然后我像这样配置我的 Spring 应用程序......
<http-conf:conduit name="*.http-conduit">
<http-conf:tlsClientParameters secureSocketProtocol="SSL" disableCNCheck="true">
<sec:trustManagers>
<sec:keyStore type="JKS" password="password" resource="server.keystore" />
</sec:trustManagers>
<sec:keyManagers keyPassword="password">
<sec:keyStore type="pkcs12" password="password" resource="server.p12" />
</sec:keyManagers>
</http-conf:tlsClientParameters>
</http-conf:conduit>
<jaxws:client id="orgWebServiceClient"
serviceClass="org.mainco.bsorg.OrganizationWebService" address="${wsdl.url}" />
but when I run my application, I get the below error. What have I missed?
但是当我运行我的应用程序时,我收到以下错误。我错过了什么?
Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://nonprod.cbapis.org/qa2/bsorg/OrganizationService: Received fatal alert: handshake_failure
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [classes.jar:1.6.0_45]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) [classes.jar:1.6.0 _45]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) [classes.jar:1.6.0_45]
at java.lang.reflect.Constructor.newInstance(Constructor.java:513) [classes.jar:1.6.0_45]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1458) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1443) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56) [cxf-api-2.6.0.jar:2.6.0]
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:659) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) [cxf-api-2.6.0.jar:2.6.0]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) [cxf-api-2.6.0.jar:2.6.0 ]
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532) [cxf-api-2.6.0.jar:2.6.0]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464) [cxf-api-2.6.0.jar:2.6.0]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367) [cxf-api-2.6.0.jar:2.6.0]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320) [cxf-api-2.6.0.jar:2.6.0]
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89) [cxf-rt-frontend-simple-2.6.0.jar:2.6.0]
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134) [cxf-rt-frontend-jaxws-2.6.0.jar:2.6.0]
... 5 more
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) [jsse.jar:1.6]
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136) [jsse.jar:1.6]
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822) [jsse.jar:1.6]
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004) [jsse.jar:1.6]
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188) [jsse.jar:1.6]
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215) [jsse.jar:1.6]
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199) [jsse.jar:1.6]
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) [jsse.jar:1.6]
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) [jsse.jar:1.6]
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014) [classes.jar:1.6.0_45]
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230) [jsse.jar:1.6]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1395) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1337) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:42) [cxf-api-2.6.0.jar:2.6.0]
at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69) [cxf-api-2.6.0.jar:2.6.0]
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1415) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
... 15 more
回答by Drona
If you are not doing a two-way SSL authentication meaning, your server does not care about who the client is so it does not need to check and verify the client certificate; then in that case all you need on the client side is just a trust store which contains a list of trusted server certificates. In your case, your client truststore would just contain the self signed server certificate and thats all. It is usual practice in java to have your truststore in .jks format. If you manage to generate a the truststore then you are set. On the server side you need not worry about the truststore but need to configure the server to have a valid server certificate.
如果你不做双向 SSL 认证的意思,你的服务器并不关心客户端是谁,所以它不需要检查和验证客户端证书;那么在这种情况下,您在客户端所需的只是一个包含受信任服务器证书列表的信任库。在您的情况下,您的客户端信任库将只包含自签名服务器证书,仅此而已。在 Java 中,通常的做法是让您的信任库采用 .jks 格式。如果您设法生成信任库,那么您就设置好了。在服务器端,您不必担心信任库,但需要将服务器配置为具有有效的服务器证书。
In a two-way SSL authentication, you need keystore and truststore both configured on both the client and server side . Client truststore would remain same as in the case of 1-way authentication. Server truststore should contain the self signed client certificate. Both client and server should be configured to use their respective certificates which they present to each othe during SSL handshake. During handshake both parties verify each other's certificate against their truststore and establish the opposite party's identity. And once the identities are established then you should be able to establish the connection.
在双向 SSL 身份验证中,您需要在客户端和服务器端都配置密钥库和信任库。客户端信任库将与单向身份验证的情况相同。服务器信任库应包含自签名客户端证书。客户端和服务器都应配置为使用各自的证书,在 SSL 握手期间,它们向彼此提供这些证书。在握手期间,双方根据他们的信任库验证彼此的证书并建立对方的身份。一旦建立了身份,您就应该能够建立连接。
For generating stores I would suggest to use a tool called Porteclewhich can be quite handy.
对于生成商店,我建议使用名为Portecle的工具,它非常方便。
回答by Chris
Here are the sequence of things you need to check for:
以下是您需要检查的一系列事项:
- Check for your entry in keystore using
keytool -list
. Refer thisarticle for syntax - Check if there are a common set of supported cipher suites between your client and server
- Finally, point the file to
.jks
in bothkeyManagers
andtrustManagers
as mentioned in cxf documentation