2012-04-01 8 views
22

Quali sono le differenze se provo a connettermi a un "https" utilizzando HttpURLConnection e HttpsURLConnection?Utilizzo di HttpURLConnection e HttpsURLConnection per connettersi a un https?

Sono stato in grado di connettersi a "https" utilizzando sia HttpURLConnection e HttpsURLConnection quindi sono confuso. Ho pensato che può solo stabilire una connessione a un "https" se ho usato HttpsURLConnection?

Qui di seguito sono alcune delle mie domande:

  • Se sono stato in grado di aprire una connessione a un "https" usando HttpURLConnection, la mia connessione è ancora in "https" o diventa "http"?
  • E la convalida dei certificati? Poiché non ho acquistato SSLSocketFactory e HostnameVerifier sul mio HttpURLConnection mentre mi collego a "https", che cosa uso SSLSocketFactory e HostnameVerifier?
  • Significa che mi sto fidando di tutto, indipendentemente dal fatto che il certificato sia attendibile o meno?

risposta

17
  1. Connessione HTTPS in uso.
  2. Comportamenti predefiniti
  3. Non sicuro, ma leggi di seguito.

Ho appena scritto del codice come test (vedere fino in fondo). Quello che succede è che la chiamata URL.openConnection() ti restituirà una classe libcore.net.http.HttpsURLConnectionImpl.

Questa è un'implementazione di HttpsURLConnection ma HttpsURLConnection eredita da HttpURLConnection. Quindi stai vedendo il polimorfismo al lavoro.

Guardando oltre nel debugger, sembra che la classe stia utilizzando i metodi di fabbrica predefiniti.

hostnameVerifier = javax.net.ssl.DefaultHostnameVerifier

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

Sulla base di questo sembra che i comportamenti predefiniti vengono utilizzati. Non so se questo significa che ti stai fidando di tutto ma stai definitivamente stabilendo una connessione HTTPS.

I suggerimenti della documentazione relativi alla connessione autorizzano le CA che sono ben note ma non autofirmate. (vedi sotto) Non ho provato questo, ma hanno codice di esempio su how to accomplish that here.

Se un'applicazione vuole fidarsi di Certificate Authority (CA) certificati che non fanno parte del sistema, si deve specificare il proprio X509TrustManager tramite uno SSLSocketFactory impostato sul 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

Grazie! Ho provato a collegarmi a diversi siti Web https usando il tuo codice. Il comportamento predefinito di SSLSocketFactory è accettare solo certificati firmati da CA. Ho ricevuto un sun.security.validator.ValidatorException quando ho provato a collegarmi a un sito Web il cui certificato è autofirmato. Grazie per il chiarimento! – Arci

+1

Vedo, quindi se sai che il server accetta solo gli URI HTTPS, puoi usare tranquillamente 'HttpURLConnection' per fare le tue richieste? – Micro