SSLHandshakeException:在Android应用程序

时间:2016-05-31 09:08:22

标签: android retrofit2

我正在为我的公司开发一个应用,需要在 https 网址上发布一些数据。

我正在使用复古,但我收到以下错误SSLHandshakeException: Connection closed by peer

这是我正在使用的代码

服务生成器

public class ServiceGenerator {

    public static final String API_BASE_URL = "https://website.com/api/";

    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    public static <S> S createService(Class<S> serviceClass) {
        Retrofit retrofit = builder.client(httpClient.build()).build();
        return retrofit.create(serviceClass);
    }
}

服务

public interface ITrackTraceService {

    @Headers("Content-Type: application/json")
    @POST("beepbeep/postdata")
    Call<String> PostLocation(@Body DataInput input);

}

自称

Location location = getLocation();

        TrackTraceService.ITrackTraceService srv = ServiceGenerator.createService(TrackTraceService.ITrackTraceService.class);

        DataInput i = new DataInput();
        i.Eta = new Date();
        i.Reference = "123456789";
        i.Status = "Tracking";
        i.Device = new Device();
        i.Reading = new Reading();
        i.Reading.Time = new Date();
        i.Reading.Location = new DeviceLocation();
        i.Reading.Location.Accuracy = location.getAccuracy();
        i.Reading.Location.Altitude = (float) location.getAltitude();
        i.Reading.Location.Latitude = (float) location.getLatitude();
        i.Reading.Location.Longitude = (float) location.getLongitude();
        i.Reading.Location.Speed = (float) location.getSpeed();
        i.Reading.Location.Time = new Date(location.getTime());
        Call<String> call = srv.PostLocation(i);

        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {

                if (response.isSuccessful()) {
                    Log.d("Service", "onResponse");
                } else {
                    // error response, no access to resource?
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable throwable) {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                throwable.printStackTrace(pw);
                Log.d("Service", call.request().toString());
                Log.e("Service", "onFailure", throwable);
                Log.d("Error", throwable.getMessage());
            }
        });
    }

版本

compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile files('libs/converter-gson-2.0.2.jar')
compile files('libs/okhttp-3.3.1.jar')
compile files('libs/gson-2.6.2.jar')
compile files('libs/okio-1.8.0.jar')
compile files('libs/retrofit-2.0.2.jar')
compile files('libs/logging-interceptor-3.3.1.jar')
building for android API version 23

栈跟踪

javax.net.ssl.SSLHandshakeException: Connection closed by peer
    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:318)
    at okhttp3.internal.io.RealConnection.connectTls(RealConnection.java:239)
    at okhttp3.internal.io.RealConnection.establishProtocol(RealConnection.java:196)
    at okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:171)
    at okhttp3.internal.io.RealConnection.connect(RealConnection.java:111)
    at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187)
    at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123)
    at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93)
    at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
    at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
    at okhttp3.RealCall.getResponse(RealCall.java:243)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
    at okhttp3.RealCall.access$100(RealCall.java:30)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
    Suppressed: javax.net.ssl.SSLHandshakeException: Connection closed by peer

2 个答案:

答案 0 :(得分:0)

我遇到了同样的问题

但对于我来说,问题是我的deviceconnectedwifi的地方,但是wifi路由器是not具有internet的连接,然后exception被抛出了

答案 1 :(得分:-2)

如果您在没有有效证书的服务器上测试应用程序,则可能会发生此错误。

最好的方法是获得授权的SSL证书。

如果是测试服务器,则尝试在项目中添加此代码,并在调用Web服务之前调用它 PS:在将您的应用上传到PlayStore之前,应删除此代码。您应该使用具有授权SSL证书的服务器。

private static void disableSSLCertificateChecking() {

    System.out.println("INSIDE DISABLE SSLC");
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // Not implemented
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // Not implemented
        }
    } };

    try {
        SSLContext sc = SSLContext.getInstance("TLS");

        sc.init(null, trustAllCerts, new java.security.SecureRandom());

        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

基本上,此代码忽略从服务器收到的任何证书(有效/无效)。

或者选中this answer

我已经读过的另一个答案(一段时间后)说明改变okhttp的版本(IDK,如果这是你的情况,但是那个人也使用了改装)可以防止这个错误。