July 25, 2018

Okhttp 3 SSL handshake Exception solved

Okhttp 3 SSL handshake issue solved


When negotiating a connection to an HTTPS server, OkHttp needs to know which TLS versions and cipher suites to offer

package com.belazy.okhttp;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;

import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.TlsVersion;

/**
 * Alan john
 *
 */
public class OkhttpSSLExample {
public static void main(String[] args) {
try {
OkHttpClient client = new OkHttpClient();
client = OkhttpSSLExample.enableTls12OVersion(client).build();
RequestBody body = RequestBody.create(null, new byte[] {});
Request request = new Request.Builder()
.url("https://freesourcecode.okhttp.com/posts/sample")
.post(body).build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
public static OkHttpClient.Builder enableTls12OVersion(OkHttpClient okHttpClient) {
OkHttpClient.Builder client = okHttpClient.newBuilder();
try {
client.connectTimeout(120, TimeUnit.SECONDS).writeTimeout(120,
TimeUnit.SECONDS).readTimeout(130, TimeUnit.SECONDS).build();
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, null);
client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));

List<CipherSuite> customCipherSuites = Arrays.asList(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384);

ConnectionSpec connectionSpec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2).cipherSuites(customCipherSuites.toArray(new CipherSuite[0]))
.build();
List<ConnectionSpec> specs = new ArrayList<>();
specs.add(connectionSpec);
specs.add(ConnectionSpec.COMPATIBLE_TLS);
specs.add(ConnectionSpec.CLEARTEXT);
client.connectionSpecs(specs);

} catch (Exception exc) {
exc.printStackTrace();
}
return client;
}
}


Use this code instead

ConnectionSpec connectionSpec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
     .tlsVersions(TlsVersion.TLS_1_2).cipherSuites(customCipherSuites.toArray(new CipherSuite[0]))
     .allEnabledTlsVersions().supportsTlsExtensions(false).allEnabledCipherSuites().build();

Okhttp works on java 1.7 or above.
API is designed in builder pattern.


OkHttp Interceptors

SLF4J with Logback to create a static singleton HttpLoggingInterceptor

private static final Logger log = LoggerFactory.getLogger(HttpClient.class);
log.debug("interceptor");
OkHttpClient interceptorClient = new OkHttpClient.Builder()
    .addInterceptor(HttpClient.getLoggingInterceptor())
    .build();


content type x-www-form-urlencoded

public static final MediaType FORM = MediaType.parse("multipart/form-data");

RequestBody formBody = new FormBody.Builder().add("likes", "Zombie movies").build();
Request request = new Request.Builder().url("https://datascientist/chippu/chunkz.php").post(formBody).build();
Response response = client.newCall(request).execute();



To enable cache

int cacheSize = 10 * 512 * 512; // 5MB
OkHttpClient.Builder builder = new OkHttpClient.Builder()
        .cache(new Cache(context.getCacheDir(), cacheSize)



No comments:

Post a Comment

Your feedback may help others !!!

Facebook comments