Android 支持HTTPS
关键点:
1.Android仅支持BouncyCastle,BKS密库
2.生成密钥
keytool -genkey -alias tomcat -keyalg RSA -keystore server.keystore -validity 3600
keytool -export -alias tomcat -file server.cer -keystore server.keystore -storepass 123456
keytool -import -alias tomcat -file server.cer -keystore server_trust.keystore -storepass 123456 -storetype BKS -providername "BC"
参见:http://anjxue.iteye.com/blog/1140275
另外使用HttpsURLConnection时需要实现HostnameVerifier 和 X509TrustManager,这两个实现是必须的,要不会报安全验证异常。然后初始化X509TrustManager中的SSLContext,为javax.net.ssl.HttpsURLConnection设置默认的SocketFactory和HostnameVerifier。
code:
1. public class HttpsDemo extends Activity implements OnClickListener
2. {
3. private static final String TAG = "HttpsDemo";
4. private static final String HTTS_URL = "https://192.168.7.39:8443/";
5. private EditText editText;
6. private Button button;
7.
8.
9. private static final String CLIENT_KET_PASSWORD = "123456";
10.
11.
12. private static final String CLIENT_TRUST_PASSWORD = "123456";
13.
14.
15. private static final String CLIENT_AGREEMENT = "TLS";
16.
17.
18. private static final String CLIENT_KEY_MANAGER = "X509";
19.
20.
21. private static final String CLIENT_TRUST_MANAGER = "X509";
22.
23.
24. private static final String CLIENT_KEY_KEYSTORE = "BKS";
25.
26.
27. private static final String CLIENT_TRUST_KEYSTORE = "BKS";
28.
29. private AssetManager mAssetManager = null;
30.
31. @Override
32. protected void onCreate(Bundle savedInstanceState)
33. {
34. super.onCreate(savedInstanceState);
35. setContentView(R.layout.https_demo);
36.
37. mAssetManager = getAssets();
38.
39. editText = (EditText) findViewById(R.id.url_entry_text);
40. button = (Button) findViewById(R.id.go_url_btn);
41.
42. editText.setText(HTTS_URL);
43. button.setOnClickListener(this);
44. }
45.
46. @Override
47. public void onClick(View v)
48. {
49. connect(editText.getText().toString());
50. }
51.
52. private void connect(String httpsUrl)
53. {
54. java.net.URL url = null;
55. HttpsURLConnection conn = null;
56. InputStream inputs = null;
57.
58. try
59. {
60. //取得SSL的SSLContext实例
61. SSLContext sslContext = SSLContext.getInstance(CLIENT_AGREEMENT);
62. //取得KeyManagerFactory实例
63. KeyManagerFactory keyManager = KeyManagerFactory
64. .getInstance(CLIENT_KEY_MANAGER);
65. //取得TrustManagerFactory的X509密钥管理器
66. TrustManagerFactory trustManager = TrustManagerFactory
67. .getInstance(CLIENT_TRUST_MANAGER);
68.
69. //取得BKS密库实例
70. KeyStore keyKeyStore = KeyStore.getInstance(CLIENT_KEY_KEYSTORE);
71. KeyStore trustKeyStore = KeyStore
72. .getInstance(CLIENT_TRUST_KEYSTORE);
73.
74. //加载证书和私钥,通过读取资源文件的方式读取密钥和信任证书(kclient:密钥;lt_client:信任证书)
75. InputStream is = mAssetManager.open("trust.keystore");
76. //kclient:密钥
77. keyKeyStore.load(is, CLIENT_KET_PASSWORD.toCharArray());
78. is.reset();
79. //lt_client:信任证书
80. trustKeyStore.load(is, CLIENT_TRUST_PASSWORD.toCharArray());
81. is.close();
82.
83. //初始化密钥管理器、信任证书管理器
84. keyManager.init(keyKeyStore, CLIENT_KET_PASSWORD.toCharArray());
85. trustManager.init(trustKeyStore);
86.
87. //初始化SSLContext
88. sslContext.init(keyManager.getKeyManagers(),
89. trustManager.getTrustManagers(), null);
90.
91. url = new URL(HTTS_URL);
92. conn = (HttpsURLConnection) url.openConnection();
93. conn.setSSLSocketFactory(sslContext.getSocketFactory());
94. conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
95.
96. conn.setDoInput(true);
97. conn.setDoOutput(true);
98. conn.setRequestProperty("Accept", "*/*");
99. conn.setRequestProperty("Pragma", "No-cache");
100. conn.setRequestProperty("Cache-Control", "no-cache");
101. conn.setRequestProperty("connection", "keep-alive");
102. conn.setRequestProperty("accept-charset", "utf-8");
103. conn.setRequestProperty("Content-Type", "text/xml");
104.
105. conn.setConnectTimeout(30000);
106. conn.setReadTimeout(30000);
107.
108. conn.setRequestMethod("GET");
109.
110. // 执行到该句就是开始建立连接并取得连接的响应结果
111. int code = conn.getResponseCode();
112.
113. Log.i(TAG, "http response code is " + code);
114.
115. inputs = conn.getInputStream();
116.
117. int size = conn.getContentLength();
118.
119. Log.i(TAG, "getContentLength" + size);
120.
121. byte[] buf = new byte[10000];
122. inputs.read(buf);
123. Log.d(TAG, "res:" + new String(buf));
124.
125. }
126. catch (MalformedURLException e)
127. {
128. e.printStackTrace();
129. }
130. catch (IOException e)
131. {
132. e.printStackTrace();
133. }
134. catch (NoSuchAlgorithmException e)
135. {
136. e.printStackTrace();
137. }
138. catch (KeyManagementException e)
139. {
140. e.printStackTrace();
141. }
142. catch (KeyStoreException e)
143. {
144. e.printStackTrace();
145. }
146. catch (CertificateException e)
147. {
148. e.printStackTrace();
149. }
150. catch (UnrecoverableKeyException e)
151. {
152. e.printStackTrace();
153. }
154. finally
155. {
156. if (conn != null)
157. {
158. conn.disconnect();
159. }
160. }
161.
162. }
163.
164. public class TrustAnyHostnameVerifier implements HostnameVerifier
165. {
166. public boolean verify(String hostname, SSLSession session)
167. {
168. return true;
169. }
170. }
171. }