【问题标题】:Paypal Sandbox TLS update (400) Bad RequestPaypal 沙盒 TLS 更新 (400) 错误请求
【发布时间】:2016-02-18 06:17:05
【问题描述】:

Paypal 沙盒已更新为使用 TLS 1.2 (https://devblog.paypal.com/upcoming-security-changes-notice/#tls)。在我没有任何更改的情况下,我看到了“handshake_failure”错误。

我已按照https://github.com/paypal/TLS-update#paypal-java-sdk-support 中的建议更新了我们使用的 JAVA 库。我使用的是旧的 1.x 版本。

但是,PayPal 会抛出 PayPalException。

[com.paypal.sdk.exceptions.TransactionException] (http-localhost/127.0.0.1:8082-7) (400)Bad Request:

除了更新 paypal_base.jar (soap),我还使用 VM 选项“-Dhttps.protocols=TLSv1.1,TLSv1.2”,但没有任何区别。

我使用的贝宝端点是

https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token=

我已尝试使用https://developer.paypal.com/docs/classic/api/endpoints/ 中提供的端点 API 签名 -> SOAP -> 沙箱,但没有成功。

对还需要做什么有什么建议吗?

更新

我运行了他们提供的测试应用程序(TlsCheck.java / jar),结果如下

java "-Dhttps.protocols=TLSv1.1,TLSv1.2" -jar TlsCheck.jar 
this client supports TLS 1.2
Failed to connect to TLS 1.2 endpoint

在浏览器中访问端点 tlstest.paypal.com 会返回“400 错误请求”。将端点更改为https://tlstest.paypal.com 会按预期返回“PayPal_Connection_OK”。

我还制作了 TlsCheck.java 的副本(使用其默认端点 tlstest.paypal.com)并通过我的 IDE 运行它,它返回以下内容(尽管它最初无法连接)

this client supports TLS 1.2
Successfully connected to TLS 1.2 endpoint

尝试与“api-3t.sandbox.paypal.com/2.0/”等其他端点相同,但无法连接到它说明

Failed to connect to TLS 1.2 endpoint

更新

原来我使用 TslCheck.jar 的测试失败了,因为 JAR 中使用的端点是“tlscheck.chargify.com”(无效??),但源代码(来自同一位置 https://github.com/paypal/TLS-update/tree/master/java)使用了不同的端点“tlstest.paypal.com”(有效)。

更新

尽管更新了 paypal_base.jar,但我目前看到“没有名为 PayPalAPIAA 的服务可用”,这最终导致 404 错误请求。还确认我在轴库中使用 HTTP/1.0 作为 HTTPSender,我们使用默认为 HTTP/1.1。我还没有找到绕过它的正确方法。我尝试按照https://www-10.lotus.com/ldd/pfwiki.nsf/dx/10022008035400PMWEBRCB.htm 切换到HTTP/1.1。这在我的情况下不起作用!!!!

【问题讨论】:

  • 不是 Java 开发人员,所以这听起来可能很愚蠢 - 您是否明确强制使用 TLS 1.2(仅)连接?这是我必须在 .Net 中进行的更改(客户端可能支持更多协议,1.1 和 1.2,但在调用 Paypal 时必须使用 1.2)。嗯……
  • 在将协议显式设置为 TLSv1.2 (java -Dhttps.protocols=TLSv1.2 -jar TlsCheck.jar) 时,我仍然使用他们的测试应用程序得到相同的结果。

标签: java soap paypal paypal-sandbox tls1.2


【解决方案1】:

这适用于 paypal TLS 1.2 新 SHA 256 证书。

*) 从 paypal 沙盒账户 -> 商家销售工具 -> apiaccess 下载 paypal_cert.pem。 *) 运行 openssl pkcs12 -export -in cert_key_pem.txt -inkey cert_key_pem.txt -out paypal_cert.p12

public HashMap httpcall(String methodName, String nvpRequestStr) {

    String version = "2.3";
    String agent = "Mozilla/4.0";
    String respText = "";
    HashMap nvp = null;

    String encodedData = "METHOD=" + methodName + "&VERSION=" + gv_Version + "&PWD=" + gv_APIPassword + "&USER=" + gv_APIUserName + nvpRequestStr;

    try
    {

            KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
            KeyStore keyStore = KeyStore.getInstance("PKCS12");

            InputStream keyInput = new FileInputStream("/Users/Downloads/paypal_cert.p12");
            keyStore.load(keyInput, "changeit".toCharArray());
            keyInput.close();
            keyManagerFactory.init(keyStore, "changeit".toCharArray());

            SSLContext context = SSLContext.getInstance("TLSV1.2");
            context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());

            URL url = new URL(gv_APIEndpoint);
            HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
            conn.setSSLSocketFactory(context.getSocketFactory());
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty( "Content-Length", String.valueOf( encodedData.length()) );
            conn.setRequestMethod("POST");

            DataOutputStream output = new DataOutputStream( conn.getOutputStream());
            output.writeBytes( encodedData );
            output.flush();
            output.close ();

            // Read input from the input stream.
            DataInputStream  in = new DataInputStream (conn.getInputStream());
            int rc = conn.getResponseCode();
            if ( rc != -1)
            {
                BufferedReader is = new BufferedReader(new InputStreamReader( conn.getInputStream()));
                String _line = null;
                while(((_line = is.readLine()) !=null))
                {
                    respText = respText + _line;
                }
                nvp = deformatNVP( respText );
            }
            return nvp;
    } catch (NoSuchAlgorithmException e) {e.printStackTrace(); return null;
    } catch (UnknownHostException e) {e.printStackTrace(); return null;
    } catch (IOException e) {e.printStackTrace(); return null;
    } catch (KeyManagementException e) {e.printStackTrace(); return null;
    } catch (UnrecoverableKeyException e) {e.printStackTrace(); return null;
    } catch (CertificateException e) {e.printStackTrace(); return null;
    } catch (KeyStoreException e) {e.printStackTrace(); return null;}
}


public HashMap deformatNVP( String pPayload )
{
    HashMap nvp = new HashMap();
    StringTokenizer stTok = new StringTokenizer( pPayload, "&");
    while (stTok.hasMoreTokens())
    {
        StringTokenizer stInternalTokenizer = new StringTokenizer( stTok.nextToken(), "=");
        if (stInternalTokenizer.countTokens() == 2)
        {
            String key = URLDecoder.decode( stInternalTokenizer.nextToken());
            String value = URLDecoder.decode( stInternalTokenizer.nextToken());
            nvp.put( key.toUpperCase(), value );
        }
    }
    return nvp;
}

【讨论】:

  • 谢谢。我们使用来自 paypal_base.jar 的 CallerServices 与 PayPal 进行通信。我希望我不必花这么多时间来解决这个问题:)
【解决方案2】:

我已经解决了这个问题,只需将库更新为使用 Mercersdk-2.14.117.jar、paypal-core-1.7.0.jar 和 permissionsskd-2.4.109.jar。我们使用的库已经很老了,API 调用必须使用新库进行更新,但尽管包名称发生了变化(com.paypal.soap.api urn.ebay.api)。由于 HTTP 调用是由库发出的,我们不再需要担心 HTTP/1.1。

我能够针对 PayPal 的沙盒环境对此进行测试和验证。

【讨论】:

    猜你喜欢
    • 2013-02-24
    • 2017-12-15
    • 2013-12-22
    • 2017-12-29
    • 2015-08-12
    • 2019-04-01
    • 2012-08-02
    • 2012-11-07
    • 2013-04-28
    相关资源
    最近更新 更多