it-swarm.com.de

Paypal-Sandbox-API: javax.net.ssl.SSLHandshakeException: Schwerwiegender Alarm: Handshake_failure erhalten

Ich erhalte eine Ausnahme, während ich Paypal MassPay API im Sandbox-Modus verwende.

Derselbe Code hat früher funktioniert, jetzt gibt es mir eine SSLHandshakeException. Ich denke, das liegt an den neuesten SSL-Zertifizierungsupdates 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
14
Syam Danda

Das Problem ist, dass Paypal kürzlich (19. oder 20. Januar) die Sandbox auf TLS 1.2 umgestellt hat und TLS 1 nicht mehr unterstützt. Ich vermute, dass Sie Java SE 7 oder älter verwenden. Wenn Sie ein bisschen im Netz suchen, werden Sie Folgendes finden:

Obwohl SunJSSE in der Java SE 7-Version TLS 1.1 und TLS .__ unterstützt. 1.2, keine Version ist standardmäßig für Clientverbindungen aktiviert. Einige Server implementieren die Forward-Kompatibilität nicht korrekt und sich weigern, mit TLS 1.1- oder TLS 1.2-Clients zu sprechen. Für die Interoperabilität ist SunJSSE aktiviert TLS 1.1 oder TLS 1.2 standardmäßig nicht für den Client Verbindungen.

Verknüpfung

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

Wenn Sie weitere Details zum Handshake anzeigen möchten, können Sie diese Option VM verwenden: -Djavax.net.debug=all

Dann können Sie bestätigen, dass TLS 1.2 deaktiviert ist, wenn Folgendes angezeigt wird:

*** 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 auf der Website von Paypal lesen:

Paypal aktualisiert seine Dienste so, dass TLS v1.2 für alle HTTPS erforderlich ist Verbindungen am 17. Juni 2016. Nach diesem Datum werden alle TLS v1.0 und TLS API-Verbindungen der Version 1.1 werden abgelehnt.

Höchstwahrscheinlich wird dies noch weiter verschoben.

Sie können das Problem reproduzieren und mit diesem einfachen Wegwerfcode experimentieren:

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();
22
Lachezar Balev

http-bio-9090-exec-1, RECV TLSv1-ALARM: fatal, Handshake_failure

Sieht aus wie Sie eine ältere Version von TLS verwenden. Vor kurzem (vor einigen Tagen) hat Paypal eine Änderung an seiner Sandbox vorgenommen, damit alle Verbindungen über HTTP 1.1 und TLS 1.2 hergestellt werden müssen. Stellen Sie Ihren Code so ein, dass er die neuere Version von TLS (1.2) verwendet, und prüfen Sie, ob dies hilfreich ist. Anscheinend hat es für viele Leute hier gearbeitet.

Link zur Änderungsbeschreibung im Paypal Dev Blog

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

4
0kay

Wenn Sie eine https-Anforderung von einem Web-Service oder einer eigenständigen Anwendung in Java aus aufrufen, verwenden Sie die folgende Zeile, um dies zu ermöglichen: 

System.setProperty(“https.protocols”, “TLSv1,TLSv1.1,TLSv1.2”);
1
Rohit S

Ich habe diese Woche mit dem gleichen Problem (Paypal TLS 1.2 Vs JRE 1.6) zu tun. Nach ein paar verrückten Stunden gelang es mir, das Problem mit BouncyCastle und einem Code zu lösen, auf den ich nicht stolz bin.

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
Basa

Mein Problem war, dass ich Java 7 installiert hatte, also ein Upgrade auf Java 8 und voila, die Ausnahme war nicht mehr da :)

1
joeabala