OkHTTP与PayPal的连接给出了SSLHandshakeException

时间:2016-10-28 16:27:33

标签: java okhttp

我正在使用Java 1.7(jdk1.7.0_80_64x)和

    <dependency>
        <groupId>com.squareup.okhttp</groupId>
        <artifactId>okhttp</artifactId>
        <version>2.7.5</version>
    </dependency>

通过此代码连接到Paypal ...

import java.io.IOException;
import java.util.Collections;
import java.util.List;

import com.squareup.okhttp.CipherSuite;
import com.squareup.okhttp.ConnectionSpec;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.TlsVersion;

public class Tester {

public static void main(String[] args) throws IOException {

    String httpUrl = "https://api.sandbox.paypal.com/retail/merchant/v1/invoices/";
    String jsonContent = "{'test':'test'}";

    RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonContent);
    Request request =  new Request.Builder().url(httpUrl).post(requestBody).build();
    OkHttpClient okHttpClient = new OkHttpClient();

    okHttpClient.setConnectionSpecs(createConnectionSpecs(okHttpClient));

    Response response = okHttpClient.newCall(request).execute();

    System.out.println(response.body());
}

  private static List<ConnectionSpec> createConnectionSpecs(OkHttpClient okHttpClient) {
    ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)  
        .tlsVersions(TlsVersion.TLS_1_2)
        .cipherSuites(
            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
            CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
            CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
            CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
            CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
            CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
            CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
            CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
            CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
            CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
        .build();
    return Collections.singletonList(spec);
  }

}

我正在运行应用程序时使用这些选项...

jdk1.7.0_80_64x\bin\java -Dhttps.protocols=TLSv1.2  -Djavax.net.debug=ssl,handshake

调试输出给出....

    adding as trusted cert:
  Subject: CN=TC TrustCenter Class 2 CA II, OU=TC TrustCenter Class 2 CA, O=TC TrustCenter GmbH, C=DE
  Issuer:  CN=TC TrustCenter Class 2 CA II, OU=TC TrustCenter Class 2 CA, O=TC TrustCenter GmbH, C=DE
  Algorithm: RSA; Serial number: 0x2e6a000100021fd752212c115c3b
  Valid from Thu Jan 12 14:38:43 GMT 2006 until Wed Dec 31 22:59:59 GMT 2025

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, called close()
main, called closeInternal(true)
main, called closeSocket(selfInitiated)
Exception in thread "main" java.net.UnknownServiceException: 
Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA], tlsVersions=[TLS_1_2], supportsTlsExtensions=true)], supported protocols=[TLSv1]
        at com.squareup.okhttp.internal.ConnectionSpecSelector.configureSecureSocket(ConnectionSpecSelector.java:73)
        at com.squareup.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:185)
        at com.squareup.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149)
        at com.squareup.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
        at com.squareup.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
        at com.squareup.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
        at com.squareup.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
        at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
        at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
        at com.squareup.okhttp.Call.getResponse(Call.java:286)
        at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:243)
        at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:205)
        at com.squareup.okhttp.Call.execute(Call.java:80)
        at com.jeff.Tester.main(Tester.java:29)

我可以看到它显示'忽略不可用的密码套件:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA',但我已经在密码套件中列出了它。

任何人都可以帮帮我。

1 个答案:

答案 0 :(得分:3)

更改

ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)to ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)

修复了这个问题。 (或使用JDK 8,或导入策略文件,或使用TLS_RSA_WITH_AES_128_CBC_SHA密码)

package com.jeff;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

import com.squareup.okhttp.CipherSuite;
import com.squareup.okhttp.ConnectionSpec;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.TlsVersion;

public class Tester {

    public static void main(String[] args) throws IOException {

        String httpUrl = "https://api.sandbox.paypal.com/retail/merchant/v1/invoices/";
        String jsonContent = "{'test':'test'}";

        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonContent);
        Request request =  new Request.Builder().url(httpUrl).post(requestBody).build();
        OkHttpClient okHttpClient = new OkHttpClient();

        okHttpClient.setConnectionSpecs(createConnectionSpecs(okHttpClient));

        Response response = okHttpClient.newCall(request).execute();

        System.out.println(response.body());
    }

      private static List<ConnectionSpec> createConnectionSpecs(OkHttpClient okHttpClient) {
        ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)  
            .tlsVersions(TlsVersion.TLS_1_2)
            .cipherSuites(
                CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
                CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
                CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
                CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
                CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
                CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
                CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
                CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
                CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
                CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
                CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
                CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
            .build();
        return Collections.singletonList(spec);
      }

}