0

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

1) 我可以使用“https://An IP ADDRESS HERE”作为有效的 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" });
    }
}
4

1 回答 1

4

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

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

更新以删除对 localhost 的引用(我最初认为本地托管的网站意味着与浏览器在同一台服务器上,Android 显然不是这种情况):

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

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

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

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

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

于 2012-07-08T20:58:56.467 回答