改进:在API21设备上启动时,Android应用失败了SSL握手

改进:在API21设备上启动时,Android应用失败了SSL握手,第1张

概述我正在构建一个使用Retrofit和自定义OkHttp客户端通过HTTPS获取一些JSON数据的应用程序.它可以在KitKat上正常工作.一旦我转到Android5、6或7,SSL握手就会失败.服务器支持TLSv1,仅此一项.它还使用古老的,过期的,自签名证书.使用Qualys的SSL工具进行了测试,该工具告诉我所有版本的

我正在构建一个使用Retrofit和自定义Okhttp客户端通过httpS获取一些JSON数据的应用程序.它可以在KitKat上正常工作.一旦我转到Android 5、6或7,SSL握手就会失败.

服务器支持TLSv1,仅此一项.它还使用古老的,过期的,自签名证书.使用qualys的SSL工具进行了测试,该工具告诉我所有版本的AndroID都可以连接.这是我得到的:

Okhttp客户端:

public class httpClIEnt {public static OkhttpClIEnt getUnsafeOkhttpClIEnt() {    try {        // Create a trust manager that does not valIDate certificate chains        final TrustManager[] trustAllCerts = new TrustManager[] {                new x509trustmanager() {                    @OverrIDe                    public voID checkClIEntTrusted(java.security.cert.X509Certificate[] chain, String authType) {                    }                    @OverrIDe                    public voID checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {                    }                    @OverrIDe                    public java.security.cert.X509Certificate[] getAcceptedissuers() {                        return new java.security.cert.X509Certificate[]{};                    }                }        };        // Install the all-trusting trust manager        final SSLContext sslContext = SSLContext.getInstance("TLSv1");        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());        // Create a ssl socket factory with our all-trusting manager        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();        //URL url = new URL(APIIntentService.getHostAddress());        //final SSLSocketFactory sslSocketFactory = new NoSSLv3SocketFactory(url);//            Connectionspec spec = new Connectionspec.Builder(Connectionspec.COMPATIBLE_TLS)//                    .tlsversions(Tlsversion.TLS_1_0)//                    .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)//                    .build();//            String hostname = "API.server.domain";//            CertificatePinner certificatePinner = new CertificatePinner.Builder()//                    .add(hostname, "sha256/3Iiwgs3a0qjPCnBQzW/GeHhPbZvhaJtxKvMJJVO5KdU=")//                    .build();        final OkhttpClIEnt.Builder builder = new OkhttpClIEnt.Builder();//            builder.connectionspecs(Collections.singletonList(spec));//            builder.certificatePinner(certificatePinner);            builder.sslSocketFactory(sslSocketFactory);            builder.hostnameVerifIEr(new HostnameVerifIEr() {                @OverrIDe                public boolean verify(String hostname, SSLSession session) {                    return true;                }            });            builder.authenticator(new Authenticator() {                @OverrIDe                public Request authenticate(Route route, Response response) throws IOException {                    String credential = Credentials.basic("user", "pass");                    return response.request().newBuilder()                            .header("Authorization", credential)                            .build();                }            });        OkhttpClIEnt okhttpClIEnt = builder.build();        return okhttpClIEnt;    } catch (Exception e) {        throw new RuntimeException(e);    }}

我知道此代码在安全性方面是多么可怕.我的主管要求这样做.我告诉他这有多严重.

我已经尝试了两种方法来解决我的问题,它们在那段代码中已被注释掉-证书固定和请求TLSv1以及特定的密码列表.在其他问题中找到了这两个,但是它们什么也没改变(堆栈跟踪完全相同).

堆栈跟踪

以下是堆栈跟踪的有趣内容:

I/RETROFIT: Data retrIEval Failed! javax.net.ssl.SSLHandshakeException: Handshake Failed*sniP*Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb43eb200: Failure in SSL library, usually a protocol errorerror:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:770 0xac6fedd4:0x00000000)                at       com.androID.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)

似乎AndroID突然尝试使用SSLv3,但Wireshark显示通过TLSv1的通信.它以应有的客户端Hello开头,但是服务器会立即以握手失败响应(40).

因为我全都没主意,所以极大地感谢了所有帮助.请要求是否需要澄清.

谢谢.

解决方法:

告诉主管,您的http客户端无法连接到严重不安全的httpS服务器.您可以说这是计算机的限制,唯一的选择是更新服务器.

完成后,您可以添加仅开发调试模式.为此,请启用服务器支持的密码套件.您可以从qualys工具中获取列表.

总结

以上是内存溢出为你收集整理的改进:在API21设备上启动时,Android应用失败了SSL握手全部内容,希望文章能够帮你解决改进:在API21设备上启动时,Android应用失败了SSL握手所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1091376.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存