使用HTTPS在Android Stidio中下载图像

时间:2016-02-09 19:49:20

标签: android https certificate httpurlconnection self-signed

这就是我在做的事情。我正在下载包含HTTP和HTTPS网站的JSON文件。这些网站是图像。我想在我的应用中显示这些图像。对于HTTP,它可以很好地工作,但对于HTTPS,它表示没有可下载的图像。所以基本上它没有达到HTTPS。我正在使用Android Dev网站访问HTTPS连接的方式,但这就是我认为我的问题来自的地方。 我在res / raw文件夹中有自签名证书,我使用参考资料访问它。 if语句确实打破了两个HTTP和HTTPS网站,并且据我所知可以正常工作。我可以这样做,就像我在做或有更好的方法吗? 谢谢你的帮助。

public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {

private final WeakReference<ImageView> imageViewReference;
Resources resources = null;


public ImageDownloaderTask(ImageView imageView) {
    imageViewReference = new WeakReference<ImageView>(imageView);
}

@Override
protected Bitmap doInBackground(String... params)
{
    return downloadBitmap(params[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
    if (isCancelled()) {
        bitmap = null;
    }

    if (imageViewReference != null) {
        ImageView imageView = imageViewReference.get();
        if (imageView != null) {
            if (bitmap != null) {
                imageView.setImageBitmap(bitmap);
            } else {
                Log.d("Downloading the image: ", "No Image found");
            }
        }

    }
}

//URL connection to download the image
private Bitmap downloadBitmap(String url) {

    HttpURLConnection urlConnection = null;
    HttpsURLConnection urlConnection2 = null;
    try {

        //check to see if the image is coming from a HTTP connection
        //then download via a HTTP connection
        //if not then use a HTTPS connection
        if(url.contains("https"))
        {
            try {
                Log.d("Use HTTPS", url);
                URL urlHTTPS = new URL(url);
                urlConnection2 = (HttpsURLConnection) urlHTTPS.openConnection();

                // Load CAs from an InputStream
                // (could be from a resource or ByteArrayInputStream or ...)
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                InputStream caInput = resources.getAssets().open("fusionsystemca.crt");
                Log.d("CA: ", caInput.toString());
                //InputStream caInput = new BufferedInputStream(new FileInputStream(resources.getAssets().open("myca.crt")));
                Certificate ca;
                try {
                    ca = cf.generateCertificate(caInput);
                    System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
                } finally {
                    caInput.close();
                }

                // Create a KeyStore containing our trusted CAs
                String keyStoreType = KeyStore.getDefaultType();
                KeyStore keyStore = KeyStore.getInstance(keyStoreType);
                keyStore.load(null, null);
                keyStore.setCertificateEntry("ca", ca);

                // Create a TrustManager that trusts the CAs in our KeyStore
                String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
                tmf.init(keyStore);

                // Create an SSLContext that uses our TrustManager
                SSLContext context = SSLContext.getInstance("TLS");
                context.init(null, tmf.getTrustManagers(), null);
                urlConnection2.setSSLSocketFactory(context.getSocketFactory());

                int statusCode = urlConnection2.getResponseCode();
                Log.d("URL2 Status: " , Integer.toString(statusCode));
                //check if the HTTP status code is equal to 200, which means that it is ok
                if (statusCode != 200) {
                    return null;
                }
                InputStream in = urlConnection2.getInputStream();
                if (in != null) {
                    Bitmap bitmap = BitmapFactory.decodeStream(in);
                    return bitmap;
                }
            }catch (Exception e)
            {
                urlConnection2.disconnect();
                Log.d("ImageDownloader", "Error downloading image from " + url);
            }

        }else
        {
            URL uri = new URL(url);
            urlConnection = (HttpURLConnection) uri.openConnection();
            urlConnection.setRequestMethod("GET");
            int statusCode = urlConnection.getResponseCode();
            //check if the HTTP status code is equal to 200, which means that it is ok
            if (statusCode != 200) {
                return null;
            }

            InputStream inputStream = urlConnection.getInputStream();
            if (inputStream != null) {
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            }
        }

    } catch (Exception e) {
        urlConnection.disconnect();
        Log.d("ImageDownloader", "Error downloading image from " + url);
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
        if(urlConnection2 != null)
        {
            urlConnection2.disconnect();
        }
    }
    return null;
}

//this is to add the selfsigned cert

}

编辑: 我仍然坚持这个错误 javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:未找到证书路径的信任锚。 这是证书不被接受。 我到目前为止已经将这个方法添加到代码中,以便允许每个证书,它仍然给我相同的问题。

public  void trustAllHosts() {

    X509TrustManager easyTrustManager = new X509TrustManager() {

        public void checkClientTrusted(
                X509Certificate[] chain,
                String authType) throws CertificateException {

        }

        public void checkServerTrusted(
                X509Certificate[] chain,
                String authType) throws CertificateException {

        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

    };

    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] {easyTrustManager};

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("TLS");

        sc.init(null, trustAllCerts, new java.security.SecureRandom());

        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    } catch (Exception e) {
        e.printStackTrace();
    }
}

1 个答案:

答案 0 :(得分:1)

您确定要尝试访问的ssl证书是否已被列为“受信任”?我有一个类似的问题,我试图访问一个不受信任的comodo证书的资源,所以它一直在打破..