PayPal 沙盒 API: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

我在沙盒模式下使用时遇到异常。PayPal MassPay API

相同的代码早些时候工作,现在它给了我一个.我认为这是因为PayPal最新的SSL认证更新。有人可以帮助我解决这个问题吗?SSLHandshakeException

以下是我的异常日志:

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

答案 1

问题是PayPal最近(1月19日或20日)将沙盒切换到TLS 1.2,不再支持TLS 1。我猜你正在Java SE 7或更早版本上运行。如果你在网上搜索一下,你会发现这个:

尽管 Java SE 7 发行版中的 SunJSSE 支持 TLS 1.1 和 TLS 1.2,但缺省情况下,这两个版本都不会为客户端连接启用。某些服务器未正确实现向前兼容性,并拒绝与 TLS 1.1 或 TLS 1.2 客户端通信。对于互操作性,默认情况下,SunJSSE 不会为客户端连接启用 TLS 1.1 或 TLS 1.2。

链接

若要启用 TLS 1.2,可以使用 VM 的以下设置:然后它将起作用。-Dhttps.protocols=TLSv1.1,TLSv1.2

如果要查看有关握手的更多详细信息,可以使用此 VM 选项:-Djavax.net.debug=all

然后,如果您看到类似下面的内容,则可以确认TLS 1.2已禁用:

*** ClientHello, TLSv1

读取服务器响应后,将引发异常。Java 8 没有这样的问题,因为 TLS 1.2 缺省情况下处于启用状态。

目前只有沙盒受到影响。您可以在PayPal的网站上阅读:

PayPal将于 2016 年 6 月 17 日更新其服务,要求所有 HTTPS 连接都使用 TLS v1.2。在该日期之后,所有 TLS v1.0 和 TLS v1.1 API 连接都将被拒绝。

这很可能会进一步推迟。

您可以重现问题并尝试使用这个简单的丢弃代码:

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();

答案 2

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

您使用的似乎是旧版本的 TLS。PayPal最近(几天前)对其沙盒进行了更改,要求所有连接都通过HTTP 1.1和TLS 1.2完成。尝试将代码设置为使用较新版本的 TLS (1.2),看看是否有帮助。显然,它在这里为很多人工作。

链接到PayPal开发博客上的更改说明

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


推荐