Android/Java -- How to Create HTTPS Connection?
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.
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();
sock开发者_如何学PythonetFactory.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.
Look at the official Custom SSL context tutorial from Apache HttpClient.
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.
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
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 Wireshark on your developer machine.
Hope this helps
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?
This is either harmless / redundant, or you are going to send "https" requests to port 80.
精彩评论