2013-05-14 10 views
6

Ich möchte eine Spring 3 (v 3.1.1.RELEASE) -Anwendung (auf Java 1.6) erstellen, um mit einem HTTPS-Webdienst zu kommunizieren, der verwendet ein selbstsigniertes Zertifikat, das ich erstellt habe. Ich bin verwirrt darüber, wie ich meine Truststores und Keystones einrichten kann. Mit meinem selbst signierten Zertifikat, erzeugen ich eine Trapez der folgenden Befehle ..."Erhaltene fatale Warnung: handshake_failure" beim Versuch, eine Verbindung zu https Web Service herzustellen

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 

Dann konfigurierte ich meinen Frühling Anwendung wie so ...

<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}" /> 

aber wenn ich meine Anwendung ausführen, bekomme ich der unten angegebene Fehler Was habe ich verpasst?

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 
+0

Hallo Dave, wir brauchen noch ein paar Informationen. Ihr HTTPS Web Service läuft also auf welchem ​​Anwendungsserver, Tomcat? Läuft Ihre Spring-Anwendung auf demselben physikalischen Server oder einem separaten Server? – Hiro2k

+4

Können Sie dies zu den JVM-Argumenten hinzufügen: '-Djavax.net.debug = ssl, handshake, failure' und die Ergebnisse des Protokolls veröffentlichen? – Avi

+0

Auch können Sie eine ähnliche Frage von mir betrachten, in der ich das gleiche Problem hatte, und ich postete alles, das ich überprüfte, das nach viel Untersuchung mich zur Antwort führte: http://stackoverflow.com/questions/15544116/sslhandshakeexception -received-fatal-alert-handshake-failure-wenn-setting-ciph – Avi

Antwort

0

Hier sind die Folge von Dingen, die Sie brauchen zu prüfen:

  1. prüfen Sie Ihre Eingabe in Schlüsselspeicher keytool -list verwenden. Siehe this Artikel für Syntax
  2. prüfen, ob es ein gemeinsamer Satz von unterstützten Chiffriersätze zwischen Client und Server Schließlich
  3. ist, weist die Datei auf .jks sowohl keyManagers und trustManagers wie erwähnt in cxf documentation
0

Sie sollte das richtige SSL-Zertifikat in Ihrem Schlüsselspeicher haben, von dem Server, mit dem Sie eine Verbindung herstellen möchten.

Sie können Keystore mit der angegebenen Methode here erstellen.

Überprüfen Sie diese Beispiele. Diese arbeiten für mich.

example 1example 2

+0

Ihr Zertifikat sollte im Keystore sein, die Zertifikate der Server, mit denen Sie eine Verbindung herstellen möchten, sollten sich entweder im Trust Store oder im Java-Zertifikatspeicher befinden. – Raymond

3

Wenn Sie nicht eine Zwei-Wege-SSL-Authentifizierung Bedeutung tun, Ihr Server kümmert sich nicht darum, wer der Kunde ist, damit es nicht das Client-Zertifikat überprüfen und überprüfen muß; Dann brauchen Sie auf der Client-Seite nur einen Trust-Store, der eine Liste vertrauenswürdiger Server-Zertifikate enthält. In Ihrem Fall würde Ihr Client-Truststore nur das selbstsignierte Serverzertifikat enthalten, und das ist alles. In Java ist es üblich, dass Ihr Truststore im .jks-Format gespeichert wird. Wenn Sie einen Truststore erstellen, werden Sie festgelegt. Auf der Serverseite müssen Sie sich nicht um den Truststore kümmern, sondern müssen den Server so konfigurieren, dass er ein gültiges Serverzertifikat besitzt.

Bei einer bidirektionalen SSL-Authentifizierung müssen Keystore und Truststore sowohl auf Client- als auch auf Serverseite konfiguriert sein. Der Client-Truststore bleibt derselbe wie bei der 1-Wege-Authentifizierung. Der Server-Truststore sollte das selbstsignierte Clientzertifikat enthalten. Sowohl der Client als auch der Server sollten so konfiguriert sein, dass sie ihre jeweiligen Zertifikate verwenden, die sie während des SSL-Handshakes einander zur Verfügung stellen. Während des Handshakes überprüfen beide Parteien das Zertifikat des anderen gegen ihren Truststore und begründen die Identität der Gegenpartei. Und sobald die Identitäten hergestellt sind, sollten Sie in der Lage sein, die Verbindung herzustellen.

Für die Generierung von Geschäften würde ich vorschlagen, ein Tool namens Portecle zu verwenden, das ziemlich praktisch sein kann.

+0

"Dann brauchen Sie auf der Client-Seite nur einen Trust-Store, der eine Liste vertrauenswürdiger Server-Zertifikate enthält." Was passiert, wenn Sie https-Server dynamisch auf Benutzereingaben treffen. Sie kennen also die Server nicht im Voraus. Was würdest du in diesem Fall tun? – Rose