1. 程式人生 > >android https(SSL) 雙向驗證詳解

android https(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:伺服器端配置

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>

然後將伺服器端信任檔案匯入即可