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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:17:27  来源:igfitidea点击:

"Received fatal alert: handshake_failure" when trying to connect to https web service

javaspringsslkeystoretruststore

提问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:

以下是您需要检查的一系列事项:

  1. Check for your entry in keystore using keytool -list. Refer thisarticle for syntax
  2. Check if there are a common set of supported cipher suites between your client and server
  3. Finally, point the file to .jksin both keyManagersand trustManagersas mentioned in cxf documentation
  1. 使用keytool -list. 语法参考这篇文章
  2. 检查您的客户端和服务器之间是否有一组通用的受支持密码套件
  3. 最后,将文件指向.jks两者keyManagerscxf 文档中trustManagers提到的

回答by Muhammad Imran Tariq

You should have correct SSL certificate in your keystore, of server to whom you are trying to connect.

您应该在您尝试连接的服务器的密钥库中拥有正确的 SSL 证书。

You can create Keystore using method given here.

您可以使用此处给出的方法创建密钥库。

Check these examples. These are working for me.

检查这些示例。这些对我有用。

example 1example 2

示例 1示例 2