2016-01-23 8 views
14

Ich bekomme eine Ausnahme bei der Verwendung PayPal MassPay API im Sandbox-Modus.Paypal Sandbox API: javax.net.ssl.SSLHandshakeException: Erhaltene fatale Warnung: handshake_failure

Der gleiche Code arbeitete früher, jetzt gibt es mir eine SSLHandshakeException. Ich denke, dies liegt an den neuesten SSL-Zertifizierungsaktualisierungen von PayPal. Kann mir jemand helfen, dieses Problem zu beheben?

Das folgende ist mein Ausnahmeprotokoll:

http-bio-9090-exec-1, READ: TLSv1 Alert, length = 2 
http-bio-9090-exec-1, RECV TLSv1 ALERT: fatal, handshake_failure 
http-bio-9090-exec-1, called closeSocket() 
http-bio-9090-exec-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
com.paypal.core.rest.PayPalRESTException: Received fatal alert: handshake_failure 
    at com.paypal.core.rest.PayPalResource.execute(PayPalResource.java:374) 
    at com.paypal.core.rest.PayPalResource.configureAndExecute(PayPalResource.java:225) 
    at com.paypal.sdk.openidconnect.Tokeninfo.createFromAuthorizationCode(Tokeninfo.java:245) 
    at com.oldwallet.controllers.CouponPaymentController.redeemed(CouponPaymentController.java:321) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) 
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) 
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563) 
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300) 
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468) 
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338) 
    at com.paypal.core.HttpConnection.execute(HttpConnection.java:93) 
    at com.paypal.core.rest.PayPalResource.execute(PayPalResource.java:367) 
    ... 36 more 

Antwort

22

Das Problem ist, dass PayPal vor kurzem (19. oder 20. Januar) 1.2 die Sandbox zu TLS geschaltet und nicht TLS unterstützen 1 mehr. Ich nehme an, dass Sie auf Java SE 7 oder älter laufen. Wenn Sie im Netz ein wenig suchen Sie diese finden:

Obwohl SunJSSE in der Java SE 7 Release unterstützt TLS 1.1 und TLS 1.2 wird weder Version standardmäßig für Client-Verbindungen aktiviert. Einige Server implementieren die Abwärtskompatibilität nicht korrekt, und verweigern die Kommunikation mit TLS 1.1- oder TLS 1.2-Clients. Für die Interoperabilität SunJSSE aktiviert standardmäßig nicht TLS 1.1 oder TLS 1.2 für Clientverbindungen .

Link

Damit TLS 1.2 Sie die folgende Einstellung der VM verwenden können: -Dhttps.protocols=TLSv1.1,TLSv1.2 Dann wird es funktionieren.

Wenn Sie mehr Informationen über das Handshake sehen Sie das VM-Option verwenden können: -Djavax.net.debug=all

Dann bestätigen Sie, wenn Sie etwas sehen, deaktiviert wird, dass TLS 1.2:

*** ClientHello, TLSv1

Nachdem die Serverantwort gelesen wurde, wird die Ausnahme ausgelöst. Java 8 hat kein solches Problem, da TLS 1.2 standardmäßig aktiviert ist.

Derzeit ist nur die Sandbox betroffen. Sie können sich auf der PayPal-Website lesen:

PayPal seine Dienste aktualisiert am 17. Juni TLS v1.2 für alle HTTPS Verbindungen zu verlangen, 2016. Nach diesem Datum alle TLS v1.0 und TLS v1.1 API-Verbindungen werden abgelehnt.

Wahrscheinlich wird dies noch mehr verschoben werden.

Sie können das Problem und experimentieren Sie mit diesem einfachen Wegwerf-Code reproduzieren:

URL sandbox = new URL("https://api.sandbox.paypal.com/v1/oauth2/token"); 
URLConnection yc = sandbox.openConnection(); 

BufferedReader in = new BufferedReader(new InputStreamReader(
    yc.getInputStream())); 
String inputLine; 
while ((inputLine = in.readLine()) != null) 
    System.out.println(inputLine); 
in.close(); 
4

http-bio-9090-exec-1, RECV TLSv1 ALERT: fatal, handshake_failure

Sieht aus wie Sie ein verwenden ältere Version von TLS. PayPal hat kürzlich (vor ein paar Tagen) eine Änderung an seiner Sandbox vorgenommen, um zu verlangen, dass alle Verbindungen über HTTP 1.1 und TLS 1.2 ausgeführt werden. Versuchen Sie, Ihren Code so einzustellen, dass er die neuere Version von TLS (1.2) verwendet, und sehen Sie, ob das hilft. Anscheinend hat es hier für viele Leute funktioniert.

Link zur Änderung Beschreibung auf PayPal DevBlog

https://devblog.paypal.com/upcoming-security-changes-notice/

1

ich mit dem gleichen Problem (Paypal TLS 1.2 Vs JRE 1.6) in dieser Woche beschäftigt haben. Nach einigen verrückten Stunden gelang es mir, das Problem mit BouncyCastle und einem Code, auf den ich nicht stolz bin, zu lösen (genau wie ein Patch. Eine dauerhafte Lösung wird auf JRE 1.8 aktualisiert).

BouncyCastle Abhängigkeit:

<dependency> 
    <groupId>org.bouncycastle</groupId> 
    <artifactId>bcprov-jdk15on</artifactId> 
    <version>1.54</version> 
</dependency> 

Mein Arbeitscode:

package es.webtools.eencuesta.redsys.component.impl; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.Socket; 
import java.net.URL; 
import java.net.URLDecoder; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.Map.Entry; 

import org.bouncycastle.crypto.tls.CertificateRequest; 
import org.bouncycastle.crypto.tls.DefaultTlsClient; 
import org.bouncycastle.crypto.tls.TlsAuthentication; 
import org.bouncycastle.crypto.tls.TlsClientProtocol; 
import org.bouncycastle.crypto.tls.TlsCredentials; 

import es.webtools.eencuesta.common.util.HttpUtils; 

public class PayPayAPIHandler { 

    public static Map<String, String> doAPIRequest(Map<String, String> paramMap) { 

    StringBuilder data = new StringBuilder(); 
    Iterator<Entry<String, String>> paramIt = paramMap.entrySet().iterator(); 
    while (paramIt.hasNext()) { 
     Entry<String, String> param = paramIt.next(); 
     data.append(param.getKey()).append("=").append(HttpUtils.encodeUTF8(param.getValue())); 
     if (paramIt.hasNext()) { 
      data.append("&"); 
     } 
    } 

    try { 
     URL url = new URL("https://api-3t.sandbox.paypal.com/nvp"); 

     // TODO #39 Utilizar HttpConnection (Java 8 implementa TLS 1.2, necesaria para comunicación con PayPal) 
     java.security.SecureRandom secureRandom = new java.security.SecureRandom(); 
     Socket socket = new Socket(java.net.InetAddress.getByName(url.getHost()), 443); 
     TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), secureRandom); 
     DefaultTlsClient client = new DefaultTlsClient() { 
      public TlsAuthentication getAuthentication() throws IOException { 
       TlsAuthentication auth = new TlsAuthentication() { 
        // Capture the server certificate information! 
        public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) throws IOException { 
        } 

        public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException { 
         return null; 
        } 
       }; 
       return auth; 
      } 
     }; 

     protocol.connect(client); 
     java.io.OutputStream output2 = protocol.getOutputStream(); 
     output2.write(("POST " + url.getPath() + " HTTP/1.1\r\n").getBytes("UTF-8")); 
     output2.write(("Host: " + url.getHost() + "\r\n").getBytes("UTF-8")); 
     output2.write("Connection: close\r\n".getBytes("UTF-8")); // So the server will close socket immediately. 
     output2.write(("Content-Length: " + data.length() + "\r\n").getBytes("UTF-8")); // So the server will close socket immediately. 
     output2.write("Content-Type:text/plain; charset=UTF-8\r\n".getBytes("UTF-8")); // So the server will close socket immediately. 
     output2.write("\r\n".getBytes("UTF-8")); // HTTP1.1 requirement: last line must be empty line. 
     output2.write(data.toString().getBytes("UTF-8")); 
     output2.flush(); 

     InputStream input2 = protocol.getInputStream(); 
     StringBuilder stringBuffer = new StringBuilder(); 
     try { 
      InputStreamReader reader = new InputStreamReader(input2, "UTF-8"); 
      int ch; 
      while ((ch = reader.read()) > -1) { 
       stringBuffer.append((char) ch); 
      } 
      reader.close(); 
     } catch (Exception e) { 
      // Log some messages... 
     } 

     Map<String, String> result = new HashMap<String, String>(); 
     String[] lines = stringBuffer.toString().split("\r\n"); 
     String paramsLine = ""; 
     for (int i = 0; i < lines.length; i++) { 
      if (lines[i].equals("")) { 
       paramsLine = lines[i + 1]; 
       i = lines.length; 
      } 
     } 

     // El contenido de la respuesta vendrá después del salto de linea 
     for (String param : paramsLine.split("&")) { 
      String[] keyValue = param.split("="); 
      result.put(keyValue[0], URLDecoder.decode(keyValue[1], "UTF-8")); 
     } 

     return result; 
    } catch (Exception e) { 
     // Log some messages.... 
     return null; 
    } 
} 

} 
1

Wenn Sie HTTPS-Anfrage von einem Web-Service oder in einer eigenständigen Anwendung in JAVA, verwenden Sie die folgende Zeile nennen es zu machen Arbeit:

System.setProperty(“https.protocols”, “TLSv1,TLSv1.1,TLSv1.2”); 
+0

Nein, funktioniert nicht – maxivis

+0

Das hat tatsächlich funktioniert. Ich habe gerade 'System.setProperty (" https.protocols "," TLSv1.1, TLSv1.2, SSLv3, SSLv2Hello ") hinzugefügt;' Das war die Lösung für mich –

0

Mein Problem war, dass ich Java 7 installiert hatte, also habe ich auf Java aufgerüstet a 8 und voila, die ausnahme war nicht mehr da :)