android ssl双向验证
预备工具“bcprov-jdk16-141.jar”和“portecle.jar”
将“bcprov-jdk16-141.jar”部署到jdk1.6.0_03\jre\lib\ext目录下
1:服务器端的密钥库
D:\a>keytool -genkey -alias 19eMTS -validity 365 -keyalg RSA -keysize 1024 -keypass 123456 -storepass 123456 -keystore 19eMTS.keystore
您的名字与姓氏是什么?
[Unknown]: 192.168.63.34 (注意这里是主机名)
您的组织单位名称是什么?
[Unknown]: 19e
您的组织名称是什么?
[Unknown]: 19e
您所在的城市或区域名称是什么?
[Unknown]: Beijing
您所在的州或省份名称是什么?
[Unknown]: Beijing
该单位的两字母国家代码是什么
[Unknown]: CN
CN=192.168.63.34:9080, OU=19e, O=19e, L=Beijing, ST=Beijing, C=CN 正确吗?
[否]: y
2:客户端的密钥库
D:\a>keytool -genkey -alias 19eMTC -validity 365 -keyalg RSA -keysize 1024 -keypass 123456 -storepass 123456 -keystore 19eMTC.p12 -storetype PKCS12
您的名字与姓氏是什么?
[Unknown]: 19e
您的组织单位名称是什么?
[Unknown]: 19e
您的组织名称是什么?
[Unknown]: 19e
您所在的城市或区域名称是什么?
[Unknown]: Beijing
您所在的州或省份名称是什么?
[Unknown]: Beijing
该单位的两字母国家代码是什么
[Unknown]: CN
CN=19e, OU=19e, O=19e, L=Beijing, ST=Beijing, C=CN 正确吗?
[否]: y
3:导出服务器端证书
D:\a>keytool -export -file service.cer -keystore 19eMTS.keystore -alias 19emts
4:导出客户端证书
D:\a>keytool -export -file client.cer -keystore 19eMTC.p12 -alias 19emtc -storetype PKCS12
5:将客户端证书导入服务器信任证书库
D:\a>keytool -import -file client.cer -keystore 19eMTS.keystore -alias 19emtc
输入keystore密码:
所有者:CN=z, OU=j, O=z, L=bj, ST=bj, C=cn
签发人:CN=z, OU=j, O=z, L=bj, ST=bj, C=cn
序列号:52de290d
有效期: Tue Jan 21 16:00:13 CST 2014 至Wed Jan 21 16:00:13 CST 2015
证书指纹:
MD5:6E:23:29:D5:7A:13:E9:D6:7D:2C:30:62:7A:CC:9B:3F
SHA1:F9:C0:0D:D6:7C:13:98:2C:DF:A3:80:DE:4F:02:AA:D3:9E:31:EC:A6
签名算法名称:SHA1withRSA
版本: 3
信任这个认证? [否]: y
认证已添加至keystore中
7:ie验证证书是否正确
双击“19eMTC.p12”和“service.cer”加载证书
8:服务器端配置
<Connector
port="9080"
protocol="HTTP/1.1"
SSLEnabled="true"
maxThreads="800"
scheme="https"
secure="true"
compression="on"
compressionMinSize="10"
noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" clientAuth="true" (此处为true时为双向验证,为false时为服务器端单向验证)
sslProtocol="TLS" keystoreFile="/home/mobile/tomcat_5.0.28_for_mobile4.0/conf/19eMTS.keystore" keystorePass="123456" truststoreFile="/home/mobile/tomcat_5.0.28_for_mobile4.0/conf/19eMTS.keystore" truststorePass="123456" />
9:打开ie输入网址如果能打开网页则证明文件生成成功,可以歇歇河口水了。
10:由于android平台证书库只支持bks格式所以需要借助portecle.jar将19eMTC.p12转换成bks格式
10.1 打开portecle.jar,新建bks格式的证书库,并从“19eMTC.p12”文件导入密钥对
12.2 保存文件为“client.bks”
11: 导入服务器端证书“service.cer”到“client.bks”中
D:\a>keytool -import -file service.cer -keystore client.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
输入keystore密码:
所有者:CN=192.168.63.34, OU=19e, O=19e, L=bj, ST=bj, C=cn
签发人:CN=192.168.63.34, OU=19e, O=19e, L=bj, ST=bj, C=cn
序列号:52de28e3
有效期: Tue Jan 21 15:59:31 CST 2014 至Wed Jan 21 15:59:31 CST 2015
证书指纹:
MD5:5F:65:53:14:47:4A:72:D5:9D:CE:EB:91:E9:9D:C8:85
SHA1:20:67:31:DA:06:55:35:D8:0A:2A:8E:F5:3E:2D:7A:47:8A:02:FF:5A
签名算法名称:SHA1withRSA
版本: 3
信任这个认证? [否]: y
认证已添加至keystore中
12:将“client.bks”文件放入android项目的“assets”文件夹下
13:客户端代码
private DefaultHttpClient createHttpClient() {
SSLSocketFactory sf = null;
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
sf = new MySSLSocketFactory(keyStore,context);
} catch (Exception e) {
e.printStackTrace();
}
BasicHttpParams httpParams = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(httpParams,
max_total_connections);
ConnPerRouteBean perRoute = new ConnPerRouteBean(max_route_connections);
ConnManagerParams.setMaxConnectionsPerRoute(httpParams, perRoute);
ConnManagerParams.setTimeout(httpParams, wait_timeout);
HttpConnectionParams.setConnectionTimeout(httpParams, timeOut);
HttpConnectionParams.setSoTimeout(httpParams, timeOut);
HttpConnectionParams.setLinger(httpParams, 30000);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ThreadSafeClientConnManager connectionManager = new ThreadSafeClientConnManager(
httpParams, registry);
DefaultHttpClient client = new DefaultHttpClient(connectionManager,
httpParams);
return client;
}
private static class MySSLSocketFactory extends SSLSocketFactory{
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore, Context context)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException, CertificateException, IOException {
super(truststore);
KeyManagerFactory keyManager = KeyManagerFactory
.getInstance("X509");
TrustManagerFactory trustManager = TrustManagerFactory
.getInstance("X509");
// 取得BKS密库实例
KeyStore kks = KeyStore.getInstance("BKS");
KeyStore tks = KeyStore.getInstance("BKS");
// 加客户端载证书和私钥,通过读取资源文件的方式读取密钥和信任证书
kks.load(context.getAssets().open("client.bks"),
"123456".toCharArray());
tks.load(context.getAssets().open("client.bks"),
"123456".toCharArray());
// 初始化密钥管理器
keyManager.init(kks, "123456".toCharArray());
trustManager.init(tks);
// 初始化SSLContext
sslContext.init(keyManager.getKeyManagers(),
trustManager.getTrustManagers(), null);
}
@Override
public Socket createSocket() throws IOException {
// TODO Auto-generated method stub
return sslContext.getSocketFactory().createSocket();
}
@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host,
port, autoClose);
}
}
14:大功告成.
备注:
可不生成pkcs12格式的证书库文件,直接生成BKS格式的证书文件但是不能进行ie验证
命令为:
D:\a>keytool -genkey -alias 19eMTC -validity 365 -keyalg RSA -keysize 1024 -keypass 123456 -storepass 123456 -keystore 19eMTC.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
您的名字与姓氏是什么?
[Unknown]: 19e
您的组织单位名称是什么?
[Unknown]: 19e
您的组织名称是什么?
[Unknown]: 19e
您所在的城市或区域名称是什么?
[Unknown]: bj
您所在的州或省份名称是什么?
[Unknown]: bj
该单位的两字母国家代码是什么
[Unknown]: cn
CN=19e, OU=19e, O=19e, L=bj, ST=bj, C=cn 正确吗?
[否]: y
D:\a>
然后将服务器端信任文件导入即可