2011-03-30 16 views
14

Tengo un código aquí que me permite conectarme a servidores https y transferir datos. Funciona bien, pero quiero saber si lo estoy haciendo de la manera correcta y estoy haciendo una conexión segura. Por favor revisa mi trabajo. Gracias.Android/Java - ¿Cómo crear una conexión HTTPS?

public class HTTPSClient extends DefaultHttpClient 
{ 

    public HTTPSClient() 
    { 
    } 

    @Override 
    protected ClientConnectionManager createClientConnectionManager() 
    { 
     SchemeRegistry registry = new SchemeRegistry(); 

     HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; 
     final SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory(); 
     socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier); 
     //socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

     registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
     registry.register(new Scheme("https", socketFactory, 80)); 
     registry.register(new Scheme("https", socketFactory, 443)); 
     HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); 

     HttpParams params = new BasicHttpParams(); 
     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, "UTF-8"); 

     return new SingleClientConnManager(params, registry); 
    } 
} 

utilizo este código así:

HttpResponse response = mConnection.httpsClient.execute(new HttpHost("www.somehostname.com", 80), new HttpGet("https://someaddress"))); 

luego leí la respuesta de allí. Gracias de nuevo.

+0

¿qué es esto en el código anterior 'socketFactory' –

+0

Mediante el uso de este código que estoy recibiendo' javax.net.ssl.SSLPeerUnverifiedException: No pares certificate' –

Respuesta

7

Mira el tutorial Custom SSL context oficial del Apache HttpClient.

Como mencionó Stephen C, no necesita registrar el puerto 80 para el contexto https. Regístrese en lugar de http (si es necesario). Esto significa que cuando llame a una url https, se usará el socketFactory apropiado, como usted especificó.

NOTA: En la mayoría de los casos, recibirá una excepción de "Certificado no confiable" o similar cuando se conecta desde dispositivos Android a sitios con certificados personalizados o certificados de emisores no muy conocidos. Si este es el caso, debe crear un almacén de certificados personalizado para su aplicación, para que confíe en sus certificados de servidor. Si desea saber más para lograr esto, puede consultar mi blog article

Si desea verificar si su dispositivo realmente se comunica a través de una conexión segura, puede realizar la llamada al punto final https desde su emulador de Android y capture el tráfico con Wireshark en su máquina de desarrollador.

Esperanza esto ayuda

+0

Hola saxos. Seguí tus instrucciones y sigo recibiendo un error de "certificado de servidor no confiable" seguido de "TrustAnchor for CertPath no encontrado". error seguido de "java.security.cert.CertPathValidatorException: TrustAnchor para CertPath no encontrado". error. Tengo un almacén de claves válido, está importando, pero estos errores ocurren. Gracias – RyanM

+0

Hola ¿Importó todos los certificados necesarios en el orden correcto? El certificado de CA Intermedio más interno primero, la CA de raíz al fin. No importe el certificado del servidor web. Nota: Si su servidor web proporciona la cadena de certificados en el orden incorrecto (por ejemplo, la primera entrada es Root CA, la segunda entrada es la CA intermedia), seguirá recibiendo errores "No de confianza". Si este es el caso, cambie el orden en el servidor web o consulte aquí: http://stackoverflow.com/questions/4115101/apache-httpclient-on-android-producing-certpathvalidatorexception-issuername/4199518#4199518 – saxos

+0

Hola. Terminé simplemente usando una conexión de red para hacer mi comunicación ssl. Los certificados utilizados por mi servidor son bien conocidos y, por lo tanto, no tuve que hacer nada de esto. urlconnection lo maneja por mí. Gracias. – RyanM

4

soy sospechoso de esto:

registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    registry.register(new Scheme("https", socketFactory, 80)); 
    registry.register(new Scheme("https", socketFactory, 443)); 

En particular, la segunda línea. ¿Por qué registraría el puerto 80 para el esquema "https"?

Esto es ya sea inofensiva/redundante, o se le va a enviar "https" peticiones al puerto 80.

Cuestiones relacionadas