Skip to content

Instantly share code, notes, and snippets.

@PromanSEW
Last active November 24, 2018 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PromanSEW/5bffdb91223c0b47766c0dacb6679843 to your computer and use it in GitHub Desktop.
Save PromanSEW/5bffdb91223c0b47766c0dacb6679843 to your computer and use it in GitHub Desktop.
TLSv1.2 problem on Android 4.3
java.net.UnknownServiceException: Unable to find acceptable protocols.
isFallback=false, modes=[ConnectionSpec(cipherSuites=[
TLS_AES_128_GCM_SHA256,
TLS_AES_256_GCM_SHA384,
TLS_CHACHA20_POLY1305_SHA256,
TLS_AES_128_CCM_SHA256,
TLS_AES_256_CCM_8_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_256_GCM_SHA384,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA
], tlsVersions=[TLS_1_2], supportsTlsExtensions=true)],
supported protocols=[SSLv3, TLSv1]
class TLS12SocketFactory extends SSLSocketFactory {
public static final String TLS_1_2 = "TLSv1.2";
private static final String[] TLS_1_2_ONLY = { TLS_1_2 };
private final SSLSocketFactory delegate;
public TLS12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
throws IOException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) ((SSLSocket) s).setEnabledProtocols(TLS_1_2_ONLY);
return s;
}
}
private static void enableSSL(@NonNull OkHttpClient.Builder builder) {
ConnectionSpec.Builder spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS);
spec.tlsVersions(TlsVersion.TLS_1_2);
if (Build.VERSION.SDK_INT >= 20) {
spec.cipherSuites(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
} else {
/*
try { setSSLFactory(builder); }
catch (Exception ignored) {}
*/
}
builder.connectionSpecs(Collections.singletonList(spec.build()));
}
private static void setSSLFactory(@NonNull OkHttpClient.Builder builder)
throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
X509TrustManager tm = Stream.of(tmf.getTrustManagers()).select(X509TrustManager.class).findFirst().orElse(null);
if (tm == null) return;
SSLContext context = SSLContext.getInstance(TLS12SocketFactory.TLS_1_2);
context.init(null, new TrustManager[] { tm }, null);
builder.sslSocketFactory(new TLS12SocketFactory(context.getSocketFactory()), tm);
}
@PromanSEW
Copy link
Author

Stream is from Lightweight Stream API
You can use other way to get X509TrustManager

@PromanSEW
Copy link
Author

Without patching SSLSocketFactory app is crashing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment