如何使用HttpURLConnection和HttpsURLConnection连接到https?

28

如果我尝试使用 HttpURLConnectionHttpsURLConnection 连接到 "https" ,有什么区别?

我能够使用 HttpURLConnectionHttpsURLConnection 连接到 "https",所以我感到困惑。我原本认为只有使用HttpsURLConnection 才能建立到 "https" 的连接。

以下是我的一些问题:

  • 如果我使用 HttpURLConnection 成功打开到 "https" 的连接,那么我的连接是否仍然是 "https" 或变成了 "http"?
  • 验证证书怎么办?由于在连接到 "https" 时,在我的 HttpURLConnection 上没有设置 SSLSocketFactoryHostnameVerifier,那么我在使用哪个 SSLSocketFactoryHostnameVerifier
  • 这是否意味着我无论证书是否被信任都会信任所有东西?
1个回答

21
  1. 正在使用HTTPS连接。
  2. 默认行为
  3. 不确定但请看下面的内容。

我刚写了一些代码作为测试(见下文)。结果是 URL.openConnection() 调用将返回一个 libcore.net.http.HttpsURLConnectionImpl 类。

这是 HttpsURLConnection 的实现,但 HttpsURLConnection 继承自 HttpURLConnection。所以你看到了多态的工作方式。

进一步查看调试器,发现该类正在使用默认工厂方法。

hostnameVerifier = javax.net.ssl.DefaultHostnameVerifier

sslSocketFactory = org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl

基于此,看起来正在使用默认行为。我不知道这是否意味着您信任所有内容,但肯定建立了HTTPS连接。

文档有点暗示连接将自动信任众所周知但不是自签名的CA。 (见下文)我没有测试过,但他们在这里提供了如何完成此操作的示例代码

如果应用程序希望信任不属于系统的证书颁发机构(CA)证书,则应通过在 HttpsURLConnection 上设置的 SSLSocketFactory 指定自己的 X509TrustManager。

Runnable r = new Runnable() {

    public void run() {
        try {
        URL test = new URL("https://www.google.com/");
        HttpURLConnection connection = (HttpURLConnection) test.openConnection();
        InputStream is = connection.getInputStream();
        StringWriter sw = new StringWriter();
        String value = new java.util.Scanner(is).useDelimiter("\\A").next();
        Log.w("GOOGLE", value);
        } catch(Exception e) {
            Log.e("Test", e.getMessage());
        }
    }

};

Thread t = new Thread(r);
t.start();

谢谢!我使用你的代码尝试连接不同的https网站。SSLSocketFactory的默认行为是仅接受由CA签名的证书。当我尝试连接一个自签名证书的网站时,我收到了sun.security.validator.ValidatorException错误。感谢你的解释! - Arci
1
我明白了,所以如果你知道服务器只接受HTTPS URI,你可以安全地使用HttpURLConnection来发送请求吗? - Micro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接