Actually the problem is TLSv1.1 and TLSv1.2 not enabled on Android <5 by default and to connect using these latest secure protocol we must have to enable in Android <5 devices.
Because by default android device pick the highest supported protocol to establish the connection but the highest/ newest secure protocol (eg. TLSV1.1 or TLSV1.2) are not enable by default (only enabled are SSLV3.0 or TLSV1.0).
Enabling the TLSV1.1 and TLSV1.2 in android < 5
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/**
* @author Bajrang Hudda
*/
public class MyTLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public MyTLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}
And now add it in your Okhttpclient -
protected static OkHttpClient getHttpClient(long timeout){
String hostname = Constants.HOST_NAME_DEBUG;
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add(hostname, "sha1/mBN/TTGneHe2Hq0yFG+SRt5nMZQ=")
.add(hostname, "sha1/6CgvsAgBlX3PYiYRGedC0NZw7ys=")
.build();
//specifying the specs; this is impotent otherwise android <5 won't work
//And do note to include the android < 5 supported specs.
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_1, 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_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
.build();
final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setCertificatePinner(certificatePinner);
okHttpClient.setConnectionSpecs(Collections.singletonList(spec));
try
{
// enabling the tlsv1.1 and tlsv.2
okHttpClient.setSslSocketFactory(new MyTLSSocketFactory());
} catch (KeyManagementException e)
{
e.printStackTrace();
} catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return okHttpClient;
}
And now finally add it in your retrofit -
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Constants.API_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setErrorHandler(new ErrorHandler())
.setClient(getHttpClient())
.setRequestInterceptor(new SecureHeaderInterceptor(null))
.build();
That's it, Happy Coding :-)