Android的:无法通过HTTPS访问本地网站 [英] Android: Unable to access a local website over HTTPS

查看:188
本文介绍了Android的:无法通过HTTPS访问本地网站的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图访​​问一个本地托管网站,并获得其HTML源代码进行解析。我有几个问题:

1)我可以使用https://开头的IP地址HERE作为一个有效的URL,试图访问。我不想做在/ etc / hosts中更改文件,所以我想这样做这样的。

2)我不能得到的HTML,因为它给我握手异常和证书的问题。我已经尝试了很多可用的帮助在Web上,但我不是成功的。

下面是code我使用的:

 公共类MainActivity延伸活动{
    私人TextView的TextView的;
    串响应=;
    串finalresponse =;
    / **当第一次创建活动调用。 * /    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);
        TextView的=(的TextView)findViewById(R.id.TextView01);
        System.setProperty(javax.net.ssl​​.trustStore中,C:\\\\ \\\\用户*);
        System.setProperty(javax.net.ssl​​.trustStorePassword中,);
    }    私有类DownloadWebPageTask扩展的AsyncTask<弦乐,太虚,字符串> {        @覆盖
        保护字符串doInBackground(字符串的URL ...){            的TrustManager [] = trustAllCerts新的TrustManager [] {
                新X509TrustManager(){
                    公共java.security.cert.X509Certificate [] getAcceptedIssuers()为{
                        返回null;
                    }
                    公共无效checkClientTrusted(java.security.cert.X509Certificate []证书,字符串的authType){
                    }
                    公共无效checkServerTrusted(java.security.cert.X509Certificate []证书,字符串的authType){
                    }
                }
            };            尝试{
                的SSLContext SC = SSLContext.getInstance(SSL);
                sc.init(NULL,trustAllCerts,新java.security.SecureRandom中的());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            }赶上(例外五){
            }
            尝试{
                网址URL =新的URL(https://172.27.224.133);                HttpsURLConnection的CON =(HttpsURLConnection的)url.openConnection();                con.setHostnameVerifier(新AllowAllHostnameVerifier());
                finalresponse = readStream(con.getInputStream());
            }赶上(例外五){
                e.printStackTrace();
            }
            返回finalresponse;
        }        私人字符串readStream(InputStream的中){
            读者的BufferedReader = NULL;
            尝试{
                读者=新的BufferedReader(新的InputStreamReader(中));
                串线=;
                而((行= reader.readLine())!= NULL){
                    响应+ =行;
                }
            }赶上(IOException异常五){
                e.printStackTrace();
            } {最后
                如果(读者!= NULL){
                    尝试{
                        reader.close();
                    }赶上(IOException异常五){
                        e.printStackTrace();
                    }
                }
            }
            返回响应;
        }
        @覆盖
        保护无效onPostExecute(字符串结果){
            textView.setText(finalresponse);
        }
    }    公共无效readWebpage(查看视图){
        DownloadWebPageTask任务=新DownloadWebPageTask();
        task.execute(新的String [] {https://172.27.224.133});
    }
}


解决方案

使用问题 https://开头的本地IP地址来访问SSL保护的网页是,这将很可能导致与浏览器信任网站的SSL证书的问题。

这是因为浏览器将试图通过检查主机名的HTTPS URL被用来验证SSL证书相匹配包含在SSL中的 CN = 主机名证书。

更新,以删除引用到本地主机(我原本以为本地托管的网站意味着相同的服务器浏览器,它与Android显然不是这样的):

您可以通过更改本地主机表,包括包含在SSL证书中的完全合格的主机名和名称与您要使用的特定IP地址关联避免此验证错误。

替代硬编码的IP地址在/ etc / hosts中

如果您对SSL证书是如何创建的,你可以添加额外的主机名,并使用使用者替代名称或SAN甚至IP地址到您的证书控制。如果您使用的是自签名证书,这可能是一个可行的选择。

不过,如果你的本地托管的网站,也可以从Internet访问你很可能使用的是购买SSL证书和硬编码的IP地址到这样的证书更将最有可能导致支持问题,随着时间的推移内部IP地址可以在需要回购的SSL证书时间而改变。

另一个选择可能是硬code您的内部IP地址,如果你有超过该服务器控制移动设备使用的DNS服务器。

I am trying to access a locally hosted website and get its HTML source to parse. I have few questions:

1) Can I use "https://An IP ADDRESS HERE" as a valid URL to try and access. I do not want to make changes in the /etc/hosts file so I want to do it this way.

2) I cannot get the html, since it is giving me Handshake exceptions and Certificate issues. I have tried a lot of help available over the web , but am not successful.

Here is the code I am using:

public class MainActivity extends Activity {
    private TextView textView;
    String response = "";
    String finalresponse="";


    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.TextView01);
        System.setProperty("javax.net.ssl.trustStore","C:\\User\\*" );
        System.setProperty("javax.net.ssl.trustStorePassword", "" );
    }

    private class DownloadWebPageTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {



            TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }
            };

            try {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
            }


            try {
                URL url = new URL("https://172.27.224.133");

                HttpsURLConnection con =(HttpsURLConnection)url.openConnection();

                con.setHostnameVerifier(new AllowAllHostnameVerifier());
                finalresponse=readStream(con.getInputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return finalresponse;
        }

        private String readStream(InputStream in) {
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(in));
                String line = "";
                while ((line = reader.readLine()) != null) {
                    response+=line;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return response;
        } 


        @Override
        protected void onPostExecute(String result) {
            textView.setText(finalresponse);
        }
    }

    public void readWebpage(View view) {
        DownloadWebPageTask task = new DownloadWebPageTask();
        task.execute(new String[] { "https://172.27.224.133" });
    }
}

解决方案

The problem with using https://local-ip-address to access an SSL protected web page is that this will most likely lead to an issue with the browser trusting the web site's SSL certificate.

This is because the browser will attempt to validate the SSL certificate by checking that the host name being used in the HTTPS URL matches the CN= host name contained inside the SSL certificate.

Updated to remove reference to localhost (I originally thought that locally hosted web site meant on the same server as the browser, which with Android is obviously not the case) :

You can avoid this validate error by changing your local host table to include the fully qualified host name contained in the SSL certificate and associating that name with the specific IP address you want to use.

Alternatives to hard-coding IP address in /etc/hosts

If you have control over how the SSL certificate is created you can add additional host names and even IP addresses to your certificate using Subject Alternate Names or SAN. This may be a viable option if you are using a self-signed certificate.

However, if your locally hosted web site is also accessed from the Internet you are more than likely using a purchased SSL certificate and hard-coding IP addresses into such a certificate will most likely lead to a support issue over time as internal IP address can change over time requiring repurchasing an SSL certificate.

Another option might be to hard-code your internal IP address into the DNS server that the mobile device is using if you have control over that server.

这篇关于Android的:无法通过HTTPS访问本地网站的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆