I have android application that was working fine for most of devices Recently some hackers tried to make DDOS attack on our servers that force us to add some security and some firewalls
not some devices are not working and give me the following exception
javax.net.ssl.SSLException: SSL handshake aborted: ssl=0x63eb8240: I/O error during system call, Connection reset by peer
can any one please tell me what is the problem now and how can I solve it ?
EDIT
this is the code of my execute method
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;
}
Use this in your code before making any network call
/**
* 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();
}
}
I had the same problem and this piece of code solved my problem. FYI: I was using retrofit library for making network calls
You need to include below line in build.gradle
implementation 'com.google.android.gms:play-services-safetynet:17.0.0
Thanks @Houman for the above input
Different Android API levels have different support for SSL/TLS protocols versions, for details see in Android Documention - https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
To enable TLS 1.1 and 1.2 you need to create a custom 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;
}
}
And then use it in your connection
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
TLSSocketFactory socketFactory = new TLSSocketFactory();
conn.setSSLSocketFactory(socketFactory);
conn.connect();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With