繁体   English   中英

Android:无法通过HTTPS访问本地网站

[英]Android: Unable to access a local website over HTTPS

我正在尝试访问本地托管的网站,并获取其HTML源进行解析。 我有几个问题:

1)我可以使用“ https://这里的IP地址”作为有效的URL尝试访问。 我不想在/ etc / hosts文件中进行更改,所以我想用这种方式。

2)我无法获取html,因为它给了我握手异常和证书问题。 我已经尝试了很多可通过网络获得的帮助,但是并不成功。

这是我正在使用的代码:

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" });
    }
}

使用https://local-ip-address访问受SSL保护的网页的问题在于,这很可能导致浏览器信任该网站的SSL证书。

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

更新以删除对本地主机的引用(我最初认为本地托管的网站与浏览器位于同一服务器上,而Android显然不是这种情况):

通过更改本地主机表以包括SSL证书中包含的标准主机名,并将该名称与您要使用的特定IP地址相关联,可以避免此验证错误。

在/ etc / hosts中对IP地址进行硬编码的替代方法

如果您可以控制SSL证书的创建方式,则可以使用“ Subject Alternate Names或“ SAN”向证书添加其他主机名,甚至IP地址。 如果您使用的是自签名证书,这可能是一个可行的选择。

但是,如果还可以从Internet访问本地托管的网站,则很有可能使用购买的SSL证书,并且随着时间的推移,内部IP地址可能会更改,因此将IP地址硬编码到此类证书中很可能会导致支持问题随着时间的流逝,需要重新购买SSL证书。

如果您可以控制移动服务器使用的内部IP地址,则另一种选择是将其内部IP地址硬编码到移动设备正在使用的DNS服务器中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM