2017-02-26 23 views
6

我有適用於大多數設備的Android應用程序正常工作 最近,一些黑客試圖對我們的服務器進行DDOS攻擊,迫使我們添加一些安全性和一些防火牆javax.net.ssl.SSLException:SSL握手在Android舊設備上中止

不是有些設備不工作,並給我下面的異常

javax.net.ssl.SSLException: SSL handshake aborted: ssl=0x63eb8240: I/O error during system call, Connection reset by peer 

任何一個可以告訴我什麼是現在的問題,我該怎麼解決呢?

編輯

這是我的執行方法的代碼

public static BaseResponse execute(Context context, BaseRequest request) { 

    mStartTime = System.nanoTime(); 

    BaseResponse response = new BaseResponse(); 
    DataOutputStream outputStream; 
    try { 
     URL url = new URL(request.getURL()); 
     HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); 
     urlConnection.setConnectTimeout(TIMEOUT_DURATION); 
     urlConnection.setReadTimeout(TIMEOUT_DURATION); 
     urlConnection.setRequestMethod(request.getRequestType().getValue()); 
     urlConnection.addRequestProperty("Accept", "application/json"); 
     urlConnection.addRequestProperty("Content-Type","application/json"); 
     urlConnection.setRequestProperty("Accept-Charset", CHARACTER_SET); 
     urlConnection.addRequestProperty("Device-Id", PhoneUtils.getDeviceId(context)); 
     urlConnection.addRequestProperty("Version-Number", PhoneUtils.getAppVersion(context)); 


     TLSSocketFactory socketFactory = new TLSSocketFactory(); 
     urlConnection.setSSLSocketFactory(socketFactory); 

     switch (request.getRequestType()) { 
      case POST: 
      case PUT: 
       urlConnection.setDoOutput(true); 
       if (request.getStringEntity() != null) { 
        outputStream = new DataOutputStream(urlConnection.getOutputStream()); 
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, CHARACTER_SET)); 
        writer.write(request.getStringParam()); 
        writer.close(); 
        outputStream.flush(); 
        outputStream.close(); 
       } 

       break; 
      case GET: 
       urlConnection.setDoOutput(false); 
       break; 
     } 

     urlConnection.connect(); 

     try { 
      if (urlConnection.getResponseCode() == STATUS_OK) { 
       InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream()); 
       BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 
       StringBuilder result = new StringBuilder(); 
       String line; 
       while ((line = reader.readLine()) != null) { 
        result.append(line); 
       } 

       inputStream.close(); 
       response.setResponse(convertStringToJSONObject(result.toString())); 
      } else { 
       response.setResponse(null); 
      } 
     } catch (Exception ex) { 
      response.setAppError(AppError.DATA_ERROR); 
     } 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
     response.setAppError(AppError.PARSING_ERROR); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     response.setAppError(AppError.DATA_ERROR); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     response.setAppError(AppError.DATA_ERROR); 
    } 

    return response; 
} 
+0

可能的重複[javax.net.ssl.SSLException:讀取錯誤:ssl = 0x9524b800:系統調用期間發生I/O錯誤,由對等方重置連接](http:/ /stackoverflow.com/questions/30538640/javax-net-ssl-sslexception-read-error-ssl-0x9524b800-io-error-during-system) – halileohalilei

回答

16

使用此做出的任何網絡呼叫

/** 
* Initialize SSL 
* @param mContext 
*/ 
public static void initializeSSLContext(Context mContext){ 
    try { 
     SSLContext.getInstance("TLSv1.2"); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    try { 
     ProviderInstaller.installIfNeeded(mContext.getApplicationContext()); 
    } catch (GooglePlayServicesRepairableException e) { 
     e.printStackTrace(); 
    } catch (GooglePlayServicesNotAvailableException e) { 
     e.printStackTrace(); 
    } 
} 

之前,你的代碼我有同樣的問題,這段代碼解決了我的問題。 FYI:我正在使用改造庫進行網絡調用

+0

非常感謝你,你救了我的一天:) –

+3

@Arshad你能解釋爲什麼這解決了問題,是什麼導致了問題? – sasuke

2

不同的Android API的水平有SSL不同的支持/ TLS協議版本,詳情在Android的機制的文檔看 - https://developer.android.com/reference/javax/net/ssl/SSLSocket.html

要啓用TLS 1.1和1.2,您需要創建一個自定義SSLSocketFactory - https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/

public class TLSSocketFactory extends SSLSocketFactory { 

    private SSLSocketFactory internalSSLSocketFactory; 

    public TLSSocketFactory() 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; 
    } 
} 

,然後用它在你的連接

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 
TLSSocketFactory socketFactory = new TLSSocketFactory(); 
conn.setSSLSocketFactory(socketFactory); 
conn.connect(); 
+0

我會試試看,並回復你 –

+0

HttpURLConnection中沒有方法稱爲setSSLSocketFactory,你的目標是什麼版本的Android? –

+0

HttpsURLConnection - https://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html – kb0

相關問題