0

В моем приложении мне нужно работать с SSLSocket. У меня есть этот код, который работает на Android6.0 и выше, и когда я запускаю тот же код на Android версии 5. + Я получаю HandshakeExceptionAndroid SSLSocket # getInputstream() throws HandshakeException в более ранних версиях Android 6.0

private void openSSLSocket(String mHost, int mPort){ 
    try { 
     SocketFactory sf = SSLSocketFactory.getDefault(); 
     mSocket = (SSLSocket) sf.createSocket(mHost, mPort); 
     mSocket.setEnabledProtocols(new String[]{"TLSv1"}); 
     mInputStream = mSocket.getInputStream(); 
     mOutputStream = mSocket.getOutputStream(); 

     mSocket.setSoTimeout(0); 

    }catch (Exception e){ 
     e.printStackTrace(); 
    } 
} 

Я прочитал this статьи на андроид сайте разработчика и реализовано ниже код, который я получил файл .crt для администратора сервера

private void openSSLSocketWithCA(String mHost, int mPort) { 
    try{ 

     // Load CAs from an InputStream 
     // (could be from a resource or ByteArrayInputStream or ...) 
     CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
     // From https://www.washington.edu/itconnect/security/ca/load-der.crt 

     InputStream caInput = am.open("star_******_chained.crt"); 

     Certificate ca; 
     try { 
      ca = cf.generateCertificate(caInput); 
      System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); 
     } finally { 
      caInput.close(); 
     } 

     // Create a KeyStore containing our trusted CAs 
     String keyStoreType = KeyStore.getDefaultType(); 
     KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
     keyStore.load(null, null); 
     keyStore.setCertificateEntry("ca", ca); 

     // Create a TrustManager that trusts the CAs in our KeyStore 
     String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
     tmf.init(keyStore); 

     // Create an SSLContext that uses our TrustManager 
     SSLContext context = SSLContext.getInstance("TLS"); 
     context.init(null, tmf.getTrustManagers(), null); 

     SSLSocketFactory sf = context.getSocketFactory(); 
     mSocket = (SSLSocket) sf.createSocket(mHost, mPort); 
     mSocket.setEnabledProtocols(new String[]{"TLSv1"}); 
     mInputStream = mSocket.getInputStream(); 
     mOutputStream = mSocket.getOutputStream(); 

     mSocket.setSoTimeout(0); 
    }catch (Exception e){ 
     e.printStackTrace(); 
    } 
} 

даже тогда я получаю HandshakeException при вызове mSocket.getInputStream(); Метод

здесь журнал

W/System.err: javax.net.ssl.SSLHandshakeException: Handshake failed 
W/System.err:  at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374) 
W/System.err:  at com.android.org.conscrypt.OpenSSLSocketImpl.waitForHandshake(OpenSSLSocketImpl.java:598) 
W/System.err:  at com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:560) 
W/System.err:  at *******.***.*******.common.CometSocketApi.openSSLSocketWithCA(CometSocketApi.java:464) 
+0

Java пробирается в ' SSLv3', даже если запрашивается 'TLS' (re:' SSLContext context = SSLContext.getInstance ("TLS"); '). Я предполагаю, что поддержка Android 5 совместима с Oracle Java и SSLv3; в то время как Android 6 остановился после пакета и не позволяет его (но это только предположение). Вы можете попробовать 'SSLSocketFactoryEx', предоставленный в [Которые Cipher Suites для включения SSL-сокета?] (Http://stackoverflow.com/a/23365536/608639) – jww

+0

@jww Спасибо за комментарий Я попробовал ваше предложение, но не повезло. –

ответ

0

После долгих поисков в интернете. Я приземлился на этой странице Updating security provider Наконец, это решение работает для меня

Я назвал этот кусок кода в OnCreate моей основной деятельности

try { 
     ProviderInstaller.installIfNeeded(this); 
    } catch (GooglePlayServicesRepairableException e) { 
     GooglePlayServicesUtil.getErrorDialog(e.getConnectionStatusCode(), callingActivity, 0); 
    } catch (GooglePlayServicesNotAvailableException e) { 
     Log.e("SecurityException", "Google Play Services not available."); 
    } 

Это решило мою проблему