-
-
Save Karewan/4b0270755e7053b471fdca4419467216 to your computer and use it in GitHub Desktop.
// Android 4.1+ | |
dependencies { | |
implementation 'com.squareup.okhttp3:okhttp:3.12.13' | |
implementation 'org.conscrypt:conscrypt-android:2.5.2' | |
} | |
// Android 5.0+ | |
dependencies { | |
implementation 'com.squareup.okhttp3:okhttp:4.10.0' | |
implementation 'org.conscrypt:conscrypt-android:2.5.2' | |
} |
// Init Conscrypt | |
Provider conscrypt = Conscrypt.newProvider(); | |
// Add as provider | |
Security.insertProviderAt(conscrypt, 1); | |
// Init OkHttp | |
OkHttpClient.Builder okHttpBuilder = new OkHttpClient() | |
.newBuilder() | |
.connectionSpecs(Collections.singletonList(ConnectionSpec.RESTRICTED_TLS)); | |
// OkHttp 3.12.x | |
// ConnectionSpec.COMPATIBLE_TLS = TLS1.0 | |
// ConnectionSpec.MODERN_TLS = TLS1.0 + TLS1.1 + TLS1.2 + TLS 1.3 | |
// ConnectionSpec.RESTRICTED_TLS = TLS 1.2 + TLS 1.3 | |
// OkHttp 3.13+ | |
// ConnectionSpec.COMPATIBLE_TLS = TLS1.0 + TLS1.1 + TLS1.2 + TLS 1.3 | |
// ConnectionSpec.MODERN_TLS = TLS1.2 + TLS 1.3 | |
// ConnectionSpec.RESTRICTED_TLS = TLS 1.2 + TLS 1.3 | |
try { | |
X509TrustManager tm = Conscrypt.getDefaultX509TrustManager(); | |
SSLContext sslContext = SSLContext.getInstance("TLS", conscrypt); | |
sslContext.init(null, new TrustManager[] { tm }, null); | |
okHttpBuilder.sslSocketFactory(new InternalSSLSocketFactory(sslContext.getSocketFactory()), tm); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
// Build OkHttp | |
OkHttpClient okHttpClient = okHttpBuilder.build(); |
import java.io.IOException; | |
import java.net.InetAddress; | |
import java.net.Socket; | |
import java.net.UnknownHostException; | |
import javax.net.ssl.SSLSocket; | |
import javax.net.ssl.SSLSocketFactory; | |
public final class InternalSSLSocketFactory extends SSLSocketFactory { | |
private final SSLSocketFactory mSSLSocketFactory; | |
public InternalSSLSocketFactory(SSLSocketFactory sslSocketFactory) { | |
this.mSSLSocketFactory = sslSocketFactory; | |
} | |
@Override | |
public String[] getDefaultCipherSuites() { | |
return mSSLSocketFactory.getDefaultCipherSuites(); | |
} | |
@Override | |
public String[] getSupportedCipherSuites() { | |
return mSSLSocketFactory.getSupportedCipherSuites(); | |
} | |
@Override | |
public Socket createSocket() throws IOException { | |
return enableTLSOnSocket(mSSLSocketFactory.createSocket()); | |
} | |
@Override | |
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { | |
return enableTLSOnSocket(mSSLSocketFactory.createSocket(s, host, port, autoClose)); | |
} | |
@Override | |
public Socket createSocket(String host, int port) throws IOException, UnknownHostException { | |
return enableTLSOnSocket(mSSLSocketFactory.createSocket(host, port)); | |
} | |
@Override | |
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { | |
return enableTLSOnSocket(mSSLSocketFactory.createSocket(host, port, localHost, localPort)); | |
} | |
@Override | |
public Socket createSocket(InetAddress host, int port) throws IOException { | |
return enableTLSOnSocket(mSSLSocketFactory.createSocket(host, port)); | |
} | |
@Override | |
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { | |
return enableTLSOnSocket(mSSLSocketFactory.createSocket(address, port, localAddress, localPort)); | |
} | |
private Socket enableTLSOnSocket(Socket socket) { | |
//if(socket instanceof SSLSocket) ((SSLSocket) socket).setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"}); | |
if(socket instanceof SSLSocket) ((SSLSocket) socket).setEnabledProtocols(new String[] {"TLSv1.2", "TLSv1.3"}); | |
return socket; | |
} | |
} |
Request request = new Request.Builder() | |
.url("https://tls13.1d.pw") // You can try another TLS 1.3 capable HTTPS server | |
.build(); | |
okHttpClient.newCall(request) | |
.enqueue(new Callback() { | |
@Override | |
public void onFailure(final Call call, IOException e) { | |
e.printStackTrace(); | |
Log.d(LOG, "onFailure()"); | |
} | |
@Override | |
public void onResponse(Call call,final Response response) throws IOException { | |
Log.d(LOG, "onResponse() tlsVersion=" + response.handshake().tlsVersion()); | |
Log.d(LOG, "onResponse() cipherSuite=" + response.handshake().cipherSuite().toString()); | |
// D/TestApp##: onResponse() tlsVersion=TLS_1_3 | |
// D/TestApp##: onResponse() cipherSuite=TLS_AES_256_GCM_SHA384 | |
} | |
}); |
This is my block code that throwing a java.lang.NullPointerException in android 4.4.2 kitkat:
Caused by: java.lang.IllegalStateException: Expected Android API level 21+ but was 19Security.insertProviderAt(Conscrypt.newProvider(), 1); try { OkHttpClient.Builder okHttpBuilder = new OkHttpClient().newBuilder() .connectionSpecs(Collections.singletonList(ConnectionSpec.MODERN_TLS)); } catch (ExceptionInInitializerError e) { e.printStackTrace(); } try { X509TrustManager tm = Conscrypt.getDefaultX509TrustManager(); SSLContext sslContext = SSLContext.getInstance("TLS", "Conscrypt"); sslContext.init(null, new TrustManager[] { tm }, null); okHttpBuilder.sslSocketFactory(new TLS13SocketFactory(sslContext.getSocketFactory()), tm); } catch (Exception e) { e.printStackTrace(); } Retrofit retrofitSystem = new Retrofit.Builder() .baseUrl(APIConnector.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(okHttpBuilder.build()) // Will be occured an unknown error here. .build();
OkHttp 3.13+ require Android 5.0+, for Android 4.4 you must use OkHttp 3.12.x (the 3.12.x branch is still updated).
Retrofit 2.70+ require Android 5.0+, for Android 4.4 you must use Retrofit 2.6.4.
Thank you so much, sir!!
I have just a question!
Can I use this method for android API 16+ (Jellybean 4.1+)?
It seems to me that in the past I tested on Android 4.3 and it didn't work, but you can try anyway.
It seems to me that in the past I tested on Android 4.3 and it didn't work, but you can try anyway.
But I tested my application in android 4.2 and it worked well.
I did downgrade the version of the libraries and I think for this reason that worked for me.
This was life savior thanks. Tested on android 4.1 and works like a charm.
como puedo hacerlo reconocible osea si el servidor no es TLSv1.3 que conecte con TLSv1.2. por que en mi caso pongo todos los protocolos y solo me esta funcionando el TLSv1.3 pero quiero que me funcione con todos los protocolos dependiendo de la conexión...
For the SSLContext I had to use the .newProvider() method rather than the string "Conscrypt"
. Like so:
SSLContext sslContext = SSLContext.getInstance("TLS", Conscrypt.newProvider());
When using just the string I was getting NoSuchProviderException: Conscrypt
Thanks a lot! Works great on Android 4.1.
It doesn't work in my case on my specific API 19 device, but works in emulator
This is my block code that throwing a java.lang.NullPointerException in android 4.4.2 kitkat:
Caused by: java.lang.IllegalStateException: Expected Android API level 21+ but was 19