在文章HttpClient访问https链接(一)中,介绍了如何接受所有证书(不做验证)来通过HttpClient请求Https协议的链接,这次,是要验证服务端的证书,将证书导入到可信证书库,处理这部分有两种不同的做法,一是直接载入证书,还有一种是通过keystore导入证书的形式,但是注意android只支持bks类型的keystore。下面我们将会把这两种都处理到。

第一种方法:我们把服务端的证书通过浏览器导出成cer文件。并把cer文件放在assert目录中。我们通过AssetManager对象去读取这个文件流。主要代码如下:

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
/**
* 获取HttpClient1
*
* @param mContext
* @return
*/
public static DefaultHttpClient getNewHttpClient1(Context mContext) {
if (mContext == null) {
throw new NullPointerException("null of Context!!!");
}
try {
// 读取证书
InputStream ins = mContext.getAssets().open("server.cer");
CertificateFactory cerFactory = CertificateFactory
.getInstance("X.509"); //
Certificate cer = cerFactory.generateCertificate(ins);
// 创建一个证书库,并将证书导入证书库
KeyStore trustStore = KeyStore.getInstance("PKCS", "BC");
trustStore.load(null, null);
trustStore.setCertificateEntry("trust", cer);
SSLSocketFactory sf = new SSLSocketFactory(trustStore);

HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}

第二种方法是我们将证书cer导入bks格式的keystore,道理一致,只是我们需要一些工具来辅助我们很快的完成我们的工作,这个工具的名字叫portecle,下载地址:http://sourceforge.net/projects/portecle/

简单介绍使用方法:

1
2
3
1、File -> New Keystore -> BKS
2、Tools -> Import Trusted Certificate… -> server.cer
3、File -> Save Keystore -> Input Password

保存为bks文件,我们也把server.bks拷贝到assert目录。
我们通过AssetManager对象去读取这个文件流。主要代码如下:

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
/**
* 获取HttpClient2
*
* @param mContext
* @return
*/
public static DefaultHttpClient getNewHttpClient2(Context mContext) {
if (mContext == null) {
throw new NullPointerException("null of Context!!!");
}
try {
// 读取证书
InputStream ins = mContext.getAssets().open("server.bks");
// 创建一个证书库,并将证书导入证书库
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(ins, "123456".toCharArray());// 这里的密码是保存bks时设置的密码
SSLSocketFactory sf = new SSLSocketFactory(trustStore);

HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
e.printStackTrace();
return new DefaultHttpClient();
}
}