Android/Java -- 如何创建HTTPS连接?

2022-09-04 03:45:59

我这里有代码,允许我连接到https服务器并传输数据。它工作得很好,但我想知道我是否以正确的方式做到这一点,我实际上正在建立安全连接。请检查我的工作。谢谢。

public class HTTPSClient extends DefaultHttpClient
{

    public HTTPSClient() 
    {
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager()
    {
        SchemeRegistry registry = new SchemeRegistry();

        HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
        final SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
        socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
        //socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", socketFactory, 80));
        registry.register(new Scheme("https", socketFactory, 443));
        HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "UTF-8");

        return new SingleClientConnManager(params, registry);
    }
}

我像这样使用这个代码:

HttpResponse response = mConnection.httpsClient.execute(new HttpHost("www.somehostname.com", 80), new HttpGet("https://someaddress")));

然后我从那里阅读了回复。再次感谢。


答案 1

查看Apache HttpClient的官方自定义SSL上下文教程。

正如 Stephen C 所提到的,您不需要为 https 上下文注册端口 80。而是将其注册为http(如有必要)。这意味着,当您调用 https url 时,将使用您指定的相应 socketFactory。

注意:在大多数情况下,当您从 Android 设备连接到具有自定义证书或来自不太知名的颁发者的证书的网站时,您将收到“证书不受信任”或类似的异常。如果是这种情况,则需要为应用程序创建自定义证书存储区,以便它信任您的服务器证书。如果你想知道热能做到这一点,你可以看看我的博客文章

如果要检查,如果您的设备确实通过安全连接进行通信,则可以从Android模拟器调用https端点,并在开发人员计算机上使用Wireshark捕获流量。

希望这有帮助


答案 2

我对此持怀疑态度:

    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    registry.register(new Scheme("https", socketFactory, 80));
    registry.register(new Scheme("https", socketFactory, 443));

特别是第二行。为什么要为“https”方案注册端口 80?

这要么是无害的/多余的,要么您将向端口80发送“https”请求。