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

时间:2012-07-08 20:52:42

标签: android html ssl

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

1)我可以使用“https:// 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" });
    }
}

1 个答案:

答案 0 :(得分:3)

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

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

更新以删除对localhost的引用(我原本以为本地托管的网站与浏览器位于同一服务器上,而Android显然不是这样):

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

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

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

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

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