Making a HTTPS request using Android Volley

后端 未结 10 1710
庸人自扰
庸人自扰 2020-11-28 19:34

I am trying to make a https request using this code:

RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
request = new Request

        
相关标签:
10条回答
  • 2020-11-28 20:11

    If you are using volley and want to HTTPS request or SSL Certified service then you can choose this easiest way : -->

    Step --> 1. keep .cer file into res/raw/ folder.

    Step --> 2. Use this method and replace .cer file name with your .cer file and replace your host name also.

    private SSLSocketFactory getSocketFactory() {
    
        CertificateFactory cf = null;
        try {
    
            cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = getResources().openRawResource(R.raw.cert_name);
            Certificate ca;
            try {
    
                ca = cf.generateCertificate(caInput);
                Log.e("CERT", "ca=" + ((X509Certificate) ca).getSubjectDN());
            } finally {
                caInput.close();
            }
    
    
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);
    
    
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);
    
    
            HostnameVerifier hostnameVerifier = new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
    
                    Log.e("CipherUsed", session.getCipherSuite());
                    return hostname.compareTo("10.199.89.68")==0; //The Hostname of your server.
    
                }
            };
    
    
            HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
            SSLContext context = null;
            context = SSLContext.getInstance("TLS");
    
            context.init(null, tmf.getTrustManagers(), null);
            HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
    
            SSLSocketFactory sf = context.getSocketFactory();
    
    
            return sf;
    
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    
        return  null;
    }
    

    Step --> 3. Replace this line "RequestQueue queue = Volley.newRequestQueue(this);" with "RequestQueue queue = Volley.newRequestQueue(this, new HurlStack(null, getSocketFactory()));" in request of volley.

    0 讨论(0)
  • 2020-11-28 20:20

    So far the only answer talk about adding an untrusted certificate as the solution, but since your browser doesn't complain it usually means Volley can't find the intermediate certificate that does complete the full trusted chain.

    It happened to me with LetsEncrypt certificates. Most browsers already have that intermediate certs so on browser everything looks fine, but Volley was apparently missing something.

    The solution
    Add the intermediate certificate to your webserver config. For Apache you can follow this reference:
    https://access.redhat.com/solutions/43575

    For LetsEncrypt it specifically is this file: /etc/letsencrypt/live/your.website.com/chain.pem So besides your CertificateFile and KeyFile you should already have working you now have this third line:

    SSLCertificateChainFile /etc/letsencrypt/live/your.website.com/chain.pem
    

    Just adding that line, restarting apache and Volley doesn't complain anymore and you didn't introduce any security vulnerabilities!

    0 讨论(0)
  • 2020-11-28 20:22

    Warning: The following code should not be used in production because it is vulnerable to SSL attacks

    Probably these codes below will be helpful for you:

    1.Create a HttpsTrustManager class that implements 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());
        }
    
    }
    

    2.Add HttpsTrustManager.allowAllSSL() before you make a https request:

    HttpsTrustManager.allowAllSSL();
    String  tag_string_req = "string_req";
    StringRequest strReq = new StringRequest(Request.Method.POST,
            your_https_url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            Log.d(TAG, "response :"+response);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d(TAG, "Error: " + error.getMessage());
        }
    }){
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("username", "max");
            params.put("password", "123456");
            return params;
        }
    };
    AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    
    0 讨论(0)
  • 2020-11-28 20:22

    I got the same problem when I add ssl to the domain, After 2 days gone, I found the solution the URL is getting wrong . I was using https://example.com but when I add ssl into domain the url will be change

    https://www.example.com

    And POST is working fine

    0 讨论(0)
提交回复
热议问题