HTTPS:超文本安全傳輸協議,和HTTP相比,多了一個SSL/TSL的認證過程,端口爲443。
1.peer終端發送一個request,https服務端把支持的加密算法等以證書的形式返回一個身份信息(包含ca頒發機構和加密公鑰等)。
2.獲取證書之後,驗證證書合法性。
3.隨機產生一個密鑰,並以證書當中的公鑰加密。
4.request https服務端,把用公鑰加密過的密鑰傳送給https服務端。
5.https服務端用自己的密鑰解密,獲取隨機值。
6.之後雙方傳送數據都用此密鑰加密後通信。
HTTPS流程清楚後,問題也就明顯了,驗證證書時,無法驗證。
上面提供的解決方案就是添加默認信任全部證書。以此來通過接下來的通信。
但是,這樣問題是解決了。但是覺得還是不帶靠譜(信任全部證書有點危險)。繼續噼噼啪啪的網上搜索一番。又找到了一種解決方案,其過程大致這樣的:
1.瀏覽器訪問https地址,保存提示的證書到本地,放到android項目中的assets目錄。
2.導入證書,代碼如下。
3.把證書添加爲信任。
- public static String requestHTTPSPage(Context context, String mUrl) {
- InputStream ins = null;
- String result = "";
- try {
- ins = context.getAssets().open("my.key"); // 下載的證書放到項目中的assets目錄中
- CertificateFactory cerFactory = CertificateFactory.getInstance("X.509");
- Certificate cer = cerFactory.generateCertificate(ins);
- KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");
- keyStore.load(null, null);
- keyStore.setCertificateEntry("trust", cer);
- SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore);
- Scheme sch = new Scheme("https", socketFactory, 443);
- HttpClient mHttpClient = new DefaultHttpClient();
- mHttpClient.getConnectionManager().getSchemeRegistry().register(sch);
- BufferedReader reader = null;
- try {
- HttpGet request = new HttpGet();
- request.setURI(new URI(mUrl));
- HttpResponse response = mHttpClient.execute(request);
- if (response.getStatusLine().getStatusCode() != 200) {
- request.abort();
- return result;
- }
- reader = new BufferedReader(new InputStreamReader(response
- .getEntity().getContent()));
- StringBuffer buffer = new StringBuffer();
- String line = null;
- while ((line = reader.readLine()) != null) {
- buffer.append(line);
- }
- result = buffer.toString();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (reader != null) {
- reader.close();
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (ins != null)
- ins.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return result;