Reputation: 1344
I'm having a problem in my Android app, in one of my fragments I use volley to do a network request:
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.POST,
CustomNetworkManager.getInstance(this.getActivity().getApplicationContext()).getRequestUrl(url),
requestData,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
// process response
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("FeedFragment", "Volley error: " + error.toString());
}
});
On a real device I get the following error (running API23):
D/FeedFragment: Volley error: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
In an AVD running the same API version it is working fine. I checked other similar threads but couldn't find an answer.
Thanks for your help.
edit: If anyone faces the same error, make sure you don't have any problems with your certificates (http://developer.android.com/intl/pt-br/training/articles/security-ssl.html#CommonProblems)
Upvotes: 15
Views: 29146
Reputation: 536
In my case problem was Charles. Configure/close it and everything works for me
Upvotes: 0
Reputation: 7203
Step 1: Create a HttpsTrustManager
class that implements X509TrustManager
:
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HttpsTrustManager implements X509TrustManager {
private static TrustManager[] trustManagers;
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}
public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return _AcceptedIssuers;
}
public static void allowAllSSL() {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[]{new HttpsTrustManager()};
}
try {
context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(context
.getSocketFactory());
}
}
Step 2: Add HttpsTrustManager.allowAllSSL()
before you make an HTTPS
request:
HttpsTrustManager.allowAllSSL();
Upvotes: 3
Reputation: 583
Just in case one still uses Volley...
Follow the instructions here:
https://developer.android.com/training/articles/security-ssl#java
Download the certificate file (.crt), put it into your assets directory (next to your java and res directories), then change the following code:
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
to use the file from assets:
InputStream caInput = new BufferedInputStream(getAssets().open("load-der.crt"));
Forget the part after
// Tell the URLConnection to use a SocketFactory from our SSLContext
and add one single line instead:
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
Run this code before any connections made.
That's all.
Upvotes: 4
Reputation: 242
This solved my problem trying to run my android volley app on arc welder only needs to be run once..at the initial splash activity
Upvotes: 2
Reputation: 1398
try to add this function to your Application:
/**
* Enables https connections
*/
@SuppressLint("TrulyRandom")
public static void handleSSLHandshake() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
} catch (Exception ignored) {
}
}
and then call it in your Application onCreate.
UPDATE:
This code is not relevant and shouldn't be used! it is forbidden by Google. for more information look here.
Upvotes: 35