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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5485415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:20:23  来源:igfitidea点击:

Android/Java -- How to Create HTTPS Connection?

javaandroidsslhttps

提问by RyanM

I have code here that allows me to connect to https servers and transfer data. It works just fine, but I want to know if I'm doing it the right way and I'm actually making a secure connection. Please check my work. Thanks.

我这里有允许我连接到 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);
    }
}

I use this code like so:

我像这样使用这个代码:

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

I then read the response from there. Thanks again.

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

采纳答案by saxos

Look at the official Custom SSL contexttutorial from Apache HttpClient.

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

As Stephen C mentioned, you don't need to register port 80 for the https context. Register it instead for http (if neccessary at all). This means, when you call a https url, the appropriate socketFactory, as you specified, will be used.

正如斯蒂芬 C 提到的,您不需要为 https 上下文注册端口 80。为 http 注册它(如果有必要的话)。这意味着,当您调用 https url 时,将使用您指定的相应 socketFactory。

NOTE: You will receive in most cases a "Certificate not trusted" or similar exception when you connect from Android devices to sites with custom certificates or certificates from not very well known issuers. If this is the case, you need to create a custom certificate store for your application, so that it will trust your server certificates. If you want to know hot to achieve this, you can look at my blog article

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

If you want to check, if your device is really communicating via a secured connection, you could make the call to the https endpoint from your android emulator and capture the traffic with Wiresharkon your developer machine.

如果您想检查您的设备是否真的通过安全连接进行通信,您可以从您的 android 模拟器调用 https 端点并在您的开发人员机器上使用Wireshark捕获流量。

Hope this helps

希望这可以帮助

回答by Stephen C

I'm suspicious of this:

我对此表示怀疑:

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

Particularly the 2nd line. Why would you register port 80 for the "https" scheme?

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

This is either harmless / redundant, or you are going to send "https" requests to port 80.

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