2012-04-01 37 views
22

Sự khác biệt nếu tôi cố gắng kết nối với "https" bằng cách sử dụng HttpURLConnectionHttpsURLConnection là gì?Sử dụng HttpURLConnection và HttpsURLConnection để kết nối với https?

Tôi có thể kết nối với "https" bằng cách sử dụng cả hai HttpURLConnectionHttpsURLConnection để tôi bị nhầm lẫn. Tôi nghĩ tôi chỉ có thể thiết lập một kết nối đến một "https" nếu tôi sử dụng HttpsURLConnection?

Dưới đây là một số câu hỏi của tôi:

  • Nếu tôi đã có thể mở một kết nối đến một "https" sử dụng HttpURLConnection, là kết nối của tôi vẫn còn trong "https" hay nó trở thành "http"?
  • Làm cách nào để xác thực chứng chỉ? Vì tôi không có bất kỳ SSLSocketFactoryHostnameVerifier trên HttpURLConnection của tôi trong khi kết nối với "https", bạn cần sử dụng SSLSocketFactoryHostnameVerifier?
  • Điều đó có nghĩa là tôi tin tưởng mọi thứ bất kể chứng chỉ có đáng tin cậy hay không?

Trả lời

17
  1. Kết nối HTTPS đang được sử dụng.
  2. Hành vi mặc định
  3. Không chắc chắn nhưng hãy đọc bên dưới.

Tôi vừa viết một số mã làm kiểm tra (xem tất cả cách bên dưới). Điều cuối cùng xảy ra là cuộc gọi URL URL.openConnection() sẽ trả lại cho bạn một lớp học libcore.net.http.HttpsURLConnectionImpl.

Đây là triển khai HttpsURLConnection nhưng HttpsURLConnection kế thừa từ HttpURLConnection. Vì vậy, bạn đang thấy đa hình trong công việc.

Nhìn xa hơn vào trình gỡ lỗi, có vẻ như lớp đang sử dụng các phương thức mặc định của nhà máy.

hostnameVerifier = javax.net.ssl.DefaultHostnameVerifier

SSLSocketFactory = org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl

Dựa trên điều này có vẻ như những hành vi mặc định đang được sử dụng. Tôi không biết nếu điều đó có nghĩa là nếu bạn tin tưởng mọi thứ nhưng bạn chắc chắn đang thiết lập kết nối HTTPS.

Các gợi ý về loại tài liệu tại kết nối sẽ tự động tin cậy các CA được biết rõ nhưng không tự ký. (xem bên dưới) Tôi đã không kiểm tra điều này nhưng họ có mã ví dụ trên how to accomplish that here.

Nếu một ứng dụng muốn tin tưởng Certificate Authority (CA) giấy chứng nhận mà không phải là một phần của hệ thống, nó nên xác định X509TrustManager riêng của mình thông qua một SSLSocketFactory đặt trên HttpsURLConnection.

Runnable r = new Runnable() { 

    public void run() { 
     try { 
     URL test = new URL("https://www.google.com/"); 
     HttpURLConnection connection = (HttpURLConnection) test.openConnection(); 
     InputStream is = connection.getInputStream(); 
     StringWriter sw = new StringWriter(); 
     String value = new java.util.Scanner(is).useDelimiter("\\A").next(); 
     Log.w("GOOGLE", value); 
     } catch(Exception e) { 
      Log.e("Test", e.getMessage()); 
     } 
    } 

}; 

Thread t = new Thread(r); 
t.start(); 
+0

Cảm ơn! Tôi đã thử kết nối với các trang web https khác nhau bằng cách sử dụng mã của bạn. Hành vi mặc định của SSLSocketFactory là chỉ chấp nhận các chứng nhận được ký bởi CA. Tôi đã nhận được một sun.security.validator.ValidatorException khi tôi thử kết nối với một trang web có chứng chỉ tự ký. Cảm ơn bạn đã làm rõ! – Arci

+1

Tôi hiểu, Vì vậy, nếu bạn biết máy chủ chỉ chấp nhận HTTPS URI, bạn có thể sử dụng một cách an toàn 'HttpURLConnection' để thực hiện các yêu cầu của bạn? – Micro

Các vấn đề liên quan