android – OKhttp:SSLProtocolException:SSL握手终止

我想弄清楚为什么有时候我会收到这个错误

javax.net.ssl.SSLProtocolException: SSL handshake terminated:
ssl=0x60d46c90: Failure in SSL library, usually a protocol error
error:1409443E:SSL routines:SSL3_READ_BYTES:tlsv1 alert inappropriate
fallback (external/openssl/ssl/s3_pkt.c:1256 0x60d57f40:0x00000003)

《android – OKhttp:SSLProtocolException:SSL握手终止》

发出此请求的代码:

private <T> void send(final String url, final Map<String, String> args, 
    final RequestCallback<T> callback, final Parser<T> pParser, 
    final Context pContext, final HTTP_METHOD method, 
    final Map<String, String> headers, final BODY_TYPE bodyType) {

    final Request.Builder builder = getBuilder(url);
    populateHeaders(builder, headers);
    final RequestBody body = getBody(args, bodyType);

    if(method==HTTP_METHOD.POST) {
        builder.post(body);
    } else if(method==HTTP_METHOD.GET) {
        builder.get();
    } else if(method==HTTP_METHOD.PUT) {
        builder.put(body);
    } else if(method==HTTP_METHOD.PATCH) {
        builder.patch(body);
    } else {
        throw new RuntimeException("Please specify correct method name!");
    }

    Request request = builder.build();
    debugRequest(request, whoCalledThisMethod());
    call = client.newCall(request);
    call.enqueue(new StandardRequestCallback(pContext, callback, pParser));
}

我发现,如果我的应用程序获得此异常,强制关闭它,然后重新启动它,可以成功完成请求…但是,不久之后,它再次失败,因为此SSL异常.

可能有什么不对?

UPDATE

我做了一个非常小的测试应用程序,使用okHttp食谱页面https://github.com/square/okhttp/wiki/Recipes中的代码,我已经重新编写了SSL握手异常!

06-27 13:59:08.068 30006-32692/a.b.ssltestapp W/System.err: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x60068d10: Failure in SSL library, usually a protocol error
06-27 13:59:08.068 30006-32692/a.b.ssltestapp W/System.err: error:1409443E:SSL routines:SSL3_READ_BYTES:tlsv1 alert inappropriate fallback (external/openssl/ssl/s3_pkt.c:1256 0x6006e6b0:0x00000003)
06-27 13:59:08.078 30006-32692/a.b.ssltestapp W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:568)
06-27 13:59:08.078 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.io.RealConnection.connectTls(RealConnection.java:188)
06-27 13:59:08.078 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:145)
06-27 13:59:08.078 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.io.RealConnection.connect(RealConnection.java:108)
06-27 13:59:08.078 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:188)
06-27 13:59:08.088 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:127)
06-27 13:59:08.088 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
06-27 13:59:08.088 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:289)
06-27 13:59:08.088 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:241)
06-27 13:59:08.088 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.RealCall.getResponse(RealCall.java:240)
06-27 13:59:08.088 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
06-27 13:59:08.088 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
06-27 13:59:08.098 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.RealCall.access$100(RealCall.java:30)
06-27 13:59:08.098 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
06-27 13:59:08.098 30006-32692/a.b.ssltestapp W/System.err:     at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:33)
06-27 13:59:08.098 30006-32692/a.b.ssltestapp W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
06-27 13:59:08.098 30006-32692/a.b.ssltestapp W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
06-27 13:59:08.098 30006-32692/a.b.ssltestapp W/System.err:     at java.lang.Thread.run(Thread.java:841)
06-27 13:59:08.098 30006-32692/a.b.ssltestapp W/System.err:     Suppressed: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x60068d10: Failure in SSL library, usually a protocol error
06-27 13:59:08.098 30006-32692/a.b.ssltestapp W/System.err: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1256 0x5ff9aa20:0x00000003)
06-27 13:59:08.108 30006-32692/a.b.ssltestapp W/System.err:         ... 18 more
06-27 13:59:08.108 30006-32692/a.b.ssltestapp W/System.err:     Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x60068d10: Failure in SSL library, usually a protocol error
06-27 13:59:08.108 30006-32692/a.b.ssltestapp W/System.err: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1256 0x5ff9aa20:0x00000003)
06-27 13:59:08.118 30006-32692/a.b.ssltestapp W/System.err:     at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
06-27 13:59:08.118 30006-32692/a.b.ssltestapp W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:486)
06-27 13:59:08.118 30006-32692/a.b.ssltestapp W/System.err:         ... 17 more
06-27 13:59:08.118 30006-32692/a.b.ssltestapp W/System.err: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x60068d10: Failure in SSL library, usually a protocol error
06-27 13:59:08.118 30006-32692/a.b.ssltestapp W/System.err: error:1409443E:SSL routines:SSL3_READ_BYTES:tlsv1 alert inappropriate fallback (external/openssl/ssl/s3_pkt.c:1256 0x6006e6b0:0x00000003)
06-27 13:59:08.118 30006-32692/a.b.ssltestapp W/System.err:     at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
06-27 13:59:08.118 30006-32692/a.b.ssltestapp W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:486)
06-27 13:59:08.118 30006-32692/a.b.ssltestapp W/System.err:     ... 17 more

最佳答案 这不是解决方案,但在涉及上述问题的情况下提供一些网络调试.

如果上面的问题1940中提到的网络接口存在问题,那么您可以通过实现Dns接口以及socketFactory来解决该问题.它可能是你取回两个DNS记录,一个适用于你而另一个不适用,并且在重启后它会改变.

https://github.com/yschimke/oksocial/blob/master/src/main/java/com/baulsupp/oksocial/network/DnsSelector.java

https://github.com/yschimke/oksocial/blob/master/src/main/java/com/baulsupp/oksocial/network/InterfaceSocketFactory.java

尝试通过添加调试查看结果来确认

Dns.SYSTEM.lookup(主机名)

NetworkInterface.getByInetAddress(地址)

NetworkInterface.getNetworkInterfaces()

UPDATE

Callback.OnFailure中的代码来调试此问题:

@Override
public void onFailure(final Call call, final IOException e) {
    if (call.isCanceled()) {
        SLog.w(TAG, "onFailure: Canceled");
        return;
    }

    if(e instanceof SSLException){

        try {
            Log.d(getClass().getSimpleName(), "Checking DNS hosts ... ");
            List<InetAddress> list = Dns.SYSTEM.lookup(call.request().url().host());
            Log.d(getClass().getSimpleName(), "Number of Entries: "+list.size());
            for (InetAddress address : list) {
                Log.d(getClass().getSimpleName(), address.toString());
            }
            Log.d(getClass().getSimpleName(), "End of Checking DNS hosts");

        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        }


        try {
            Log.d(getClass().getSimpleName(), "Checking Network Interfaces ... ");
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            ArrayList<NetworkInterface> list = Collections.list(interfaces);
            Log.d(getClass().getSimpleName(), "Number of Entries: "+list.size());
            for(NetworkInterface netintface : list) {
                Log.d(getClass().getSimpleName(), netintface.toString());
                List<InterfaceAddress> listaddresses = netintface.getInterfaceAddresses();
                Log.d(getClass().getSimpleName(), "   Number of Interface Addresses: "+listaddresses.size());
                for (InterfaceAddress infcaddress : listaddresses) {
                    Log.d(getClass().getSimpleName(), "   > InterfaceAddress : "+infcaddress.toString());
                }
            }
            Log.d(getClass().getSimpleName(), "End of Checking Network Interfaces");
        } catch (SocketException e1) {
            e1.printStackTrace();
        }


    }
}

来自上面代码的DEBUG OUTPUT

06-21 11:43:19.495 12890-12890/com.app.stg D/[StandardRequest]: ->
                                                                   ------------- Request -------------
                                                                   ********** METHOD sendRequest() **********
                                                                   GET
                                                                   -----------------------------------
06-21 11:43:24.330 12890-21401/com.app.stg D/StandardRequestCallback: Checking DNS hosts ... 
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: Number of Entries: 8
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: arc.stg.issa.sainsburys.co.uk/52.85.69.145
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: arc.stg.issa.sainsburys.co.uk/52.85.69.20
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: arc.stg.issa.sainsburys.co.uk/52.85.69.185
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: arc.stg.issa.sainsburys.co.uk/52.85.69.84
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: arc.stg.issa.sainsburys.co.uk/52.85.69.249
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: arc.stg.issa.sainsburys.co.uk/52.85.69.52
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: arc.stg.issa.sainsburys.co.uk/52.85.69.159
06-21 11:43:24.450 12890-21401/com.app.stg D/StandardRequestCallback: arc.stg.issa.sainsburys.co.uk/52.85.69.246
06-21 11:43:24.460 12890-21401/com.app.stg D/StandardRequestCallback: End of Checking DNS hosts
06-21 11:43:24.460 12890-21401/com.app.stg D/StandardRequestCallback: Checking Network Interfaces ... 
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback: Number of Entries: 4
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback: [lo][1][/::1%1%1][/127.0.0.1]
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback:    Number of Interface Addresses: 2
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback:    > InterfaceAddress : /::1%1%1/128 [null]
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback:    > InterfaceAddress : /127.0.0.1/8 [null]
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback: [sit0][2]
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback:    Number of Interface Addresses: 0
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback: [wlan0][4][/fe80::4283:deff:fe94:b0ff%wlan0%4][/172.24.90.253]
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback:    Number of Interface Addresses: 2
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback:    > InterfaceAddress : /fe80::4283:deff:fe94:b0ff%wlan0%4/64 [null]
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback:    > InterfaceAddress : /172.24.90.253/19 [/172.24.95.255]
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback: [ip6tnl0][3]
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback:    Number of Interface Addresses: 0
06-21 11:43:24.480 12890-21401/com.app.stg D/StandardRequestCallback: End of Checking Network Interfaces
06-21 11:43:24.480 12890-12890/com.app.stg D/JS-[LauncherActivity]: ErrorReport{type='SSLHandshakeException'}
点赞