OkHTTP Unable to find acceptable protocols (android)

Sorry for my English. I am trying to use libhel OKhttp and I am using https for post reqest. Now I have an error, when I try to publish my example, this is an error:

java.net.UnknownServiceException: Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA], tlsVersions=[TLS_1_2], supportsTlsExtensions=true)], supported protocols=[SSLv3, TLSv1] 

I am trying to fix it, but I cannot do it. I do not know that I have this error

And align my code:

 public class PostOKhttp extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String...ulr) { Response response = null; OkHttpClient client = new OkHttpClient(); ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) .tlsVersions(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_ECDSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, CipherSuite.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, CipherSuite.TLS_ECDHE_RSA_WITH_RC4_128_SHA, CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA) .build(); client.setConnectionSpecs(Collections.singletonList(spec)); RequestBody postForm = new FormEncodingBuilder() .add("name", "name") .build(); Request request = new Request.Builder() .url(ulr[0]) .addHeader("id", "--") .addHeader("key", "--") .post(postForm) .build(); try { response = client.newCall(request).execute(); Log.e("post", response.body().string()); } catch (Exception e) { Log.e("error", e.toString()); } return null; } @Override protected void onPostExecute(String result) { } 

UDP:

Use CertificatePinner

i add this code

 String link = "example.net"; CertificatePinner certificatePinner = new CertificatePinner.Builder() .add(link, "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=") .add(link, "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=") .add(link, "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=") .add(link, "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=") .build(); client.setCertificatePinner(certificatePinner); 

Now I have this error:

 javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. 
+4
android ssl
06 Sep '15 at 16:07
source share
2 answers

In fact, the default problem of TLSv1.1 and TLSv1.2 is not enabled on Android <5 by default and to connect using the latest secure protocol that must be enabled for Android devices <5.

Because by default, the android device selects the highest supported protocol to establish the connection, but the highest / newest secure protocol (e.g. TLSV1.1 or TLSV1.2) is disabled by default (only SSLV3.0 or TLSV1. 0 is enabled).

Enable 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 to 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 to your modification -

  RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(Constants.API_URL) .setLogLevel(RestAdapter.LogLevel.FULL) .setErrorHandler(new ErrorHandler()) .setClient(getHttpClient()) .setRequestInterceptor(new SecureHeaderInterceptor(null)) .build(); 

What is it, Happy coding :-)

+3
Aug 24 '17 at 5:34 on
source

You need to use ProviderInstaller to verify and install TLS support if necessary. Use something like this when entering Activity , and it should do the trick. Check more information here.

 protected void checkTls() { if (android.os.Build.VERSION.SDK_INT < 21) { try { ProviderInstaller.installIfNeededAsync(this, new ProviderInstaller.ProviderInstallListener() { @Override public void onProviderInstalled() { SSLContext sslContext = null; try { sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, null, null); SSLEngine engine = sslContext.createSSLEngine(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } } @Override public void onProviderInstallFailed(int i, Intent intent) { } }); } catch (Exception e) { e.printStackTrace(); } } } 
+1
Nov 21 '17 at 11:53 on
source



All Articles