我的android应用程序适用于大多数设备 最近一些黑客试图对我们的服务器进行DDOS攻击,迫使我们添加一些安全性和一些防火墙
某些设备无法正常工作并给我以下异常
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 :(得分:36)
在进行任何网络通话之前,请在代码中使用此功能
/**
* 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();
}
}
我遇到了同样的问题,这段代码解决了我的问题。仅供参考:我使用改造库进行网络电话
答案 1 :(得分:7)
不同的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();