如何在Android上使用Https

基础知识

HTPPS和HTTP的概念

HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。这个系统的最初研发由网景公司进行,提供了身份验证与加密通讯方法,现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。

超文本传输协议 (HTTP-Hypertext transfer protocol) 是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。

HTTPS和HTTP的区别

HTTPS协议需要到ca申请证书,一般免费证书很少,需要交费。

HTTP是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的ssl加密传输协议。

HTTP和HTTPS使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。

HTTP的连接很简单,是无状态的。

HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全

HTTPS解决的问题:信任主机的问题、通讯过程中的数据的泄密和被窜改问题。

HTTPS在Android上的使用

HTTPS Get请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.test;  

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.KeyStore;

/**
* Https get请求
*/
public class HttpsGetThread extends Thread {

private Handler handler;
private String httpUrl;
private int mWhat;

// public static final int ERROR = 404;
// public static final int SUCCESS = 200;

public HttpsGetThread(Handler handler, String httpUrl) {
super();
this.handler = handler;
this.httpUrl = httpUrl;
mWhat = 200;
}

public HttpsGetThread(Handler handler, String httpUrl, int what) {
super();
this.handler = handler;
this.httpUrl = httpUrl;
mWhat = what;
}

@Override
public void run() {
// TODO Auto-generated method stub
try {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
HttpConnectionParams.setSoTimeout(httpParameters, 10000);
HttpClient hc = getHttpClient(httpParameters);
HttpGet get = new HttpGet(httpUrl);
get.setParams(httpParameters);
HttpResponse response = null;
try {
response = hc.execute(get);
} catch (UnknownHostException e) {
throw new Exception("Unable to access "
+ e.getLocalizedMessage());
} catch (SocketException e) {
throw new Exception(e.getLocalizedMessage());
}
int sCode = response.getStatusLine().getStatusCode();
if (sCode == HttpStatus.SC_OK) {
String result = EntityUtils.toString(response.getEntity(),
HTTP.UTF_8);
handler.sendMessage(Message.obtain(handler, mWhat, result)); // 请求成功
Log.i("info", "result = " + result);
} else {
String result = EntityUtils.toString(response.getEntity(),
HTTP.UTF_8);
Log.i("info", "result = " + result);
}

} catch (Exception e) {
e.printStackTrace();
Log.i("info", "=============异常退出==============");
handler.sendMessage(Message.obtain(handler, 404, "异常退出"));
}

super.run();
}

/**
* 获取HttpClient
*
* @param params
* @return
*/
public static HttpClient getHttpClient(HttpParams params) {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(null, null);

SSLSocketFactory sf = new SSLSocketFactoryImp(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(params, true);

// 设置http https支持
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));// SSL/TSL的认证过程,端口为443
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient(params);
}
}
}

HTTPS Post请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.test;  

import android.os.Handler;
import android.os.Message;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.util.List;

/**
* Https Post请求
*/
public class HttpsPostThread extends Thread {

private Handler handler;
private String httpUrl;
private List<NameValuePair> valueList;
private int mWhat;

public static final int ERROR = 404;
public static final int SUCCESS = 200;

public HttpsPostThread(Handler handler, String httpUrl,
List<NameValuePair> list, int what) {
super();
this.handler = handler;
this.httpUrl = httpUrl;
this.valueList = list;
this.mWhat = what;
}

public HttpsPostThread(Handler handler, String httpUrl,
List<NameValuePair> list) {
super();
this.handler = handler;
this.httpUrl = httpUrl;
this.valueList = list;
this.mWhat = SUCCESS;
}

@Override
public void run() {
// TODO Auto-generated method stub
String result = null;
try {
HttpParams httpParameters = new BasicHttpParams();
// 设置连接管理器的超时
ConnManagerParams.setTimeout(httpParameters, 10000);
// 设置连接超时
HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
// 设置socket超时
HttpConnectionParams.setSoTimeout(httpParameters, 10000);
HttpClient hc = getHttpClient(httpParameters);
HttpPost post = new HttpPost(httpUrl);
post.setEntity(new UrlEncodedFormEntity(valueList, HTTP.UTF_8));
post.setParams(httpParameters);
HttpResponse response = null;
try {
response = hc.execute(post);
} catch (UnknownHostException e) {
throw new Exception("Unable to access "
+ e.getLocalizedMessage());
} catch (SocketException e) {
throw new Exception(e.getLocalizedMessage());
}
int sCode = response.getStatusLine().getStatusCode();
if (sCode == HttpStatus.SC_OK) {
result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
if (handler != null) {
handler.sendMessage(Message.obtain(handler, mWhat, result)); // 请求成功
}
} else {
result = "请求失败" + sCode; // 请求失败
// 404 - 未找到
if (handler != null) {
handler.sendMessage(Message.obtain(handler, ERROR, result));
}
}
} catch (Exception e) {
e.printStackTrace();
if (handler != null) {
result = "请求失败,异常退出";
handler.sendMessage(Message.obtain(handler, ERROR, result));
}
}
super.run();
}

/**
* 获取HttpClient
*
* @param params
* @return
*/
public static HttpClient getHttpClient(HttpParams params) {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(null, null);

SSLSocketFactory sf = new SSLSocketFactoryImp(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(params, true);

// 设置http https支持
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));// SSL/TSL的认证过程,端口为443
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient(params);
}
}
}

SSLSocketFactoryImp类:如果要进行证书认证,可以在该方法中实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.test;  

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.conn.ssl.SSLSocketFactory;

public class SSLSocketFactoryImp extends SSLSocketFactory {
final SSLContext sslContext = SSLContext.getInstance("TLS");

public SSLSocketFactoryImp(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore);

TrustManager tm = new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}

@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain, String authType)
throws java.security.cert.CertificateException {
}

@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain, String authType)
throws java.security.cert.CertificateException {
}
};

sslContext.init(null, new TrustManager[] { tm }, null);
}

@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port,
autoClose);
}

@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}

}

测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.test;  

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {
private Button btn, btn1;
private Handler mHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
initData();

}

private void initView() {
btn = (Button) findViewById(R.id.btn);
btn1 = (Button) findViewById(R.id.btn1);
}

private void initListener() {
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List<NameValuePair> list = new ArrayList<NameValuePair>();
HttpsPostThread thread = new HttpsPostThread(mHandler,
"https://certs.cac.washington.edu/CAtest/", list, 200);
thread.start();
}
});
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
HttpsGetThread thread = new HttpsGetThread(mHandler,
"https://certs.cac.washington.edu/CAtest/", 200);
thread.start();
}
});
}

private void initData() {
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
String result = (String) msg.obj;
switch (msg.what) {
case 200:
// 请求成功
Log.e("TAG", "返回参数===" + result);
break;
case 404:
// 请求失败
Log.e("TAG", "请求失败!");
break;
}

}
};
}
}