Android uses HTTPS problem Resolution (sslhandshakeexception)

Source: Internet
Author: User

title Date Categories Tags
Android 5.0 below tls1.x sslhandshakeexception 2016-11-30 12:17:02-0800
Android
Android tlsv1.x

Recently, all of the app's requests to HTTPS, in the test, some phone found that the request failed, the failure of the exception information as follows:

Javax.net.ssl.SSLHandshakeException:javax.net.ssl.SSLProtocolException:SSL Handshake Aborted:ssl=0x783e8e70: Failure in SSL Library, usually a protocol Errorerror:14077102:ssl routines:SSL23_GET_SERVER_HELLO:unsupported protocol (external/openssl/ssl/s23_clnt.c:714 0x71a20cf8:0x00000000)

The exception for the handshake failed, but why some mobile phone can be successful and the phone failed again, first check our server interface TLS support version of 1.x, and later found that the failure of the phone is 5.x below the version, presumably should be related to this, and then consult the official documents, The corresponding tables in Sslsocket that refer to the TLS version and the Android SDK version are as follows:

Protocol supported (API levels) Enabled By default (API levels)
SSLv3 1 + 1 +
TLSv1 1 + 1 +
TLSv1.1 16+ 20+
TLSv1.2 16+ 20+

As seen from this table, tlsv1.x (1.1,1.2) Android is supported by default from API16, and is available by default from API20, which explains why the phones below 5.x failed when they made the request.

Know the cause of the problem, we have to solve, of course, the server can support the TLSV1 version, so we can all request success, but this is not the best solution, we certainly want to let our app support the new TLS protocol.

Cipher suitesThere are also api20+ support or default available through official documentation, so if we want to support the tlsv1.x version, we may need to add the lower version, Cipher suites so we need to customize the sslsocketfactory, The custom sslsocketfactory are as follows:

 Public classSslextendsSslsocketfactory {Privatesslsocketfactory defaultfactory; //Android 5.0+ (API level21) provides reasonable default settings//But it still allows SSLv3// https://developer.android.com/about/versions/android-5.0-changes.html#ssl    StaticString protocols[] =NULL, ciphersuites[] =NULL; Static {        Try{sslsocket Socket=(Sslsocket) Sslsocketfactory.getdefault (). Createsocket (); if(Socket! =NULL) {                /*set Reasonable protocol versions*/                //-Enable all supported protocols (enables TLSv1.1 and TLSv1.2 on Android <5.0)//-Remove all SSL versions (especially SSLv3) because they ' re insecure nowlist<string> protocols =NewLinkedlist<>();  for(String protocol:socket.getSupportedProtocols ())if(!protocol.touppercase (). Contains ("SSL") ) protocols.add (protocol); Ssl.protocols= Protocols.toarray (Newstring[protocols.size ()]); /*set up reasonable cipher suites*/                if(Build.VERSION.SDK_INT <Build.version_codes. LOLLIPOP) {//Choose known secure cipher suitesList<string> allowedciphers =Arrays.aslist (//TLS 1.2"tls_rsa_with_aes_256_gcm_sha384",                            "Tls_rsa_with_aes_128_gcm_sha256",                            "Tls_ecdhe_ecdsa_with_aes_128_cbc_sha256",                            "Tls_ecdhe_ecdsa_with_aes_128_gcm_sha256",                            "tls_ecdhe_ecdsa_with_aes_256_gcm_sha384",                            "Tls_ecdhe_rsa_with_aes_128_cbc_sha256",                            "Tls_echde_rsa_with_aes_128_gcm_sha256",                            //Maximum Interoperability"Tls_rsa_with_3des_ede_cbc_sha",                            "Tls_rsa_with_aes_128_cbc_sha",                            //additionally"Tls_rsa_with_aes_256_cbc_sha",                            "Tls_ecdhe_ecdsa_with_3des_ede_cbc_sha",                            "Tls_ecdhe_ecdsa_with_aes_128_cbc_sha",                            "Tls_ecdhe_rsa_with_3des_ede_cbc_sha",                            "Tls_ecdhe_rsa_with_aes_128_cbc_sha"); List<String> availableciphers =arrays.aslist (Socket.getsupportedciphersuites ()); //Take all allowed ciphers that is available and put them into preferredciphersHashset<string> preferredciphers =NewHashset<>(allowedciphers);                    Preferredciphers.retainall (availableciphers); /*for maximum security, preferredciphers should *replace* enabled ciphers (thus disabling * ciphers Which is enabled by default, but has become unsecure), but I guess for * The security level of DAVD Roid and maximum compatibility, disabling of insecure * ciphers should be a server-side task*/                    //add preferred ciphers to Enabled ciphersHashset<string> enabledciphers =preferredciphers; Enabledciphers.addall (NewHashset<>(Arrays.aslist (Socket.getenabledciphersuites ()))); Ssl.ciphersuites= Enabledciphers.toarray (Newstring[enabledciphers.size ()]); }            }        } Catch(IOException e) {Throw NewRuntimeException (e); }    }     PublicSSL (X509trustmanager tm) {Try{sslcontext Sslcontext= Sslcontext.getinstance ("TLS"); Sslcontext.init (NULL, (tm! =NULL) ?NewX509TRUSTMANAGER[]{TM}:NULL,NULL); Defaultfactory=sslcontext.getsocketfactory (); } Catch(generalsecurityexception e) {Throw NewAssertionerror ();//The system has no TLS. Just give up.        }    }    Private voidUpgradetls (Sslsocket SSL) {//Android 5.0+ (API level21) provides reasonable default settings//But it still allows SSLv3// https://developer.android.com/about/versions/android-5.0-changes.html#ssl        if(Protocols! =NULL) {ssl.setenabledprotocols (protocols); }        if(Build.VERSION.SDK_INT < Build.version_codes. LOLLIPOP && Ciphersuites! =NULL) {ssl.setenabledciphersuites (ciphersuites); }} @Override Publicstring[] Getdefaultciphersuites () {returnciphersuites; } @Override Publicstring[] Getsupportedciphersuites () {returnciphersuites; } @Override PublicSocket Createsocket (socket s, String host,intPortBooleanAutoClose)throwsIOException {Socket SSL=Defaultfactory.createsocket (S, host, Port, AutoClose); if(SSLinstanceofsslsocket) Upgradetls ((sslsocket) SSL); returnSSL; } @Override PublicSocket Createsocket (String host,intPortthrowsIOException, unknownhostexception {Socket SSL=Defaultfactory.createsocket (host, Port); if(SSLinstanceofsslsocket) Upgradetls ((sslsocket) SSL); returnSSL; } @Override PublicSocket Createsocket (String host,intPort, InetAddress LocalHost,intLocalPort)throwsIOException, unknownhostexception {Socket SSL=Defaultfactory.createsocket (host, Port, LocalHost, LocalPort); if(SSLinstanceofsslsocket) Upgradetls ((sslsocket) SSL); returnSSL; } @Override PublicSocket Createsocket (inetaddress host,intPortthrowsIOException {Socket SSL=Defaultfactory.createsocket (host, Port); if(SSLinstanceofsslsocket) Upgradetls ((sslsocket) SSL); returnSSL; } @Override PublicSocket Createsocket (inetaddress address,intPort, InetAddress localaddress,intLocalPort)throwsIOException {Socket SSL=Defaultfactory.createsocket (address, Port, localaddress, LocalPort); if(SSLinstanceofsslsocket) Upgradetls ((sslsocket) SSL); returnSSL; }}

Then we just need to set this sslsocketfactory on our request, we take okhttp as an example, as follows:

//define a TrustManager that trusts all certificatesFinalX509trustmanager Trustallcert =NewX509trustmanager () {@Override Public voidCheckclienttrusted (java.security.cert.x509certificate[] chain, String authtype)throwscertificateexception {} @Override Public voidCheckservertrusted (java.security.cert.x509certificate[] chain, String authtype)throwscertificateexception {} @Override Publicjava.security.cert.x509certificate[] Getacceptedissuers () {return Newjava.security.cert.x509certificate[]{}; }};//Set OkhttpclientOkhttpclient client =NewOkhttpclient.builder (). Sslsocketfactory (NewSSL (Trustallcert), Trustallcert). Build ();

After setting up, test HTTPS with a lower version of your phone and you can now test successfully.

Android uses HTTPS problem Resolution (sslhandshakeexception)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.