mercoledì 30 gennaio 2013

Android - Connessione HTTPS con certificati client e server

Qualche giorno fa ho fatto un applicazione in cui dovevo invocare un web service in https. Scenario:
  • Il certificato del server (pub_server.crt) è self signed (firmato) da una CA personale (personal_ca.crt)
  • Il client si autentica utilizzando il proprio certificato p12 (client.p12) e in più con il proprio user e password.
Non mi metto a spiegare come si creano i certificati perché non è questo lo scopo dell'articolo.
Vi spiego i passi che ho fatto:
  1. Siccome Android utilizza il provider JCE di Bouncy Castle ho scaricato il jar bcprov-jdk16-146.jar e l'ho salvato sotto la directory lib del progetto ($workspace/mioProgetto/libs/).
  2. Importo personal_ca.crt e pub_server.crt in un unico file chiamato server_cert di tipo BKS nel miProgetto come risorsa raw ($workspace/mioProgetto/res/raw/) : 
    
    #importo il CA personale
    keytool -import -alias personalCa -file [percorso]\personal_ca.crt -keypass provapass -keystore $workspace\mioProgetto\res\raw\server_cert -storetype BKS -storepass provapass -providerClass org.bouncycastle2.jce.provider.BouncyCastleProvider -providerpath $workspace\mioProgetto\libs\bcprov-jdk16-146.jar
    #importo il certificato server
    keytool -importcert -v -trustcacerts -file [percorso]\pub_server.crt -alias serverCert -keystore $workspace\mioProgetto\res\raw\server_cert -providerClass org.bouncycastle2.jce.provider.BouncyCastleProvider -providerpath $workspace\mioProgetto\libs\bcprov-jdk16-146.jar -storetype BKS -storepass provapass
    
    
    Basta fare un refresh sulla directory res/raw per vedere il certificato importato.
  3. Salvo anche il certificato client client.p12 sotto $workspace/mioProgetto/res/raw/ 
  4.  Ora utilizzo questi certificati per fare l'autenticazione.
    
    try {
       
     SSLContext sslContext = SSLContext.getInstance("TLS");
     
     // truststore
     KeyStore trustStore = KeyStore.getInstance("BKS");
     TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
     InputStream trustStoreStream = this.getResources().openRawResource(R.raw.server_cert);
     // passo la password utilizzata quando ho importato il certificato
     trustStore.load(trustStoreStream, "provapass".toCharArray());
     trustManagerFactory.init(trustStore);
     // keystore
     KeyStore keyStore = KeyStore.getInstance("pkcs12");
     KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
     InputStream keyStoreStream = this.getResources().openRawResource(R.raw.client);
     // passo la password del certificato client
     keyStore.load(keyStoreStream, "clientpass".toCharArray());
     keyManagerFactory.init(keyStore, "clientpass".toCharArray());
    
     sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);   
     
     URL url = new URL("https://webserviceUrl");
     
     // utilizzo HttpsURLConnection per fare connessioni https
     HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
     
     // username e password
     String usernamePass = "userName:password";
     String basicAuth = new String(Base64.encode(usernamePass.getBytes()));
     
     // basic authentication
     conn.setRequestProperty("Authorization", "Basic " + basicAuth);
     conn.setRequestProperty("User-Agent", "Android Application");
      
     // non la faccio la verifica del hostname
     conn.setHostnameVerifier(new SkipVerifier());
      
     conn.setSSLSocketFactory(sslContext.getSocketFactory());
     System.out.println("Response code is " + conn.getResponseCode());
       
    } catch (Exception e) {
     largeTxt.setText(e.getMessage());
     e.printStackTrace();
    }
    
    
  5. Creo la classe SkipVerifier che implementa HostnameVerifier, che non fa altro che ritorna true per ogni hostname.
    
    public class SkipVerifier implements HostnameVerifier {
        
        @Override
        public final boolean verify(final String hostname, final SSLSession sslSession) {
      
           return true;
           
        }
    
    }
    
    
Provate e dovreste ottenere la connessione SSL con il web service.

venerdì 30 marzo 2012

Configurazione SEO per il sito in Joomla

Il passo più importante dopo aver creato un sito in Joomla è sicuramente quella di ottimizzare la propria visibilità nei motori di ricerca. Non mi metto a spiegare tutti i step per avere una buona visibilità altrimenti non avreste clickato su questo articolo, ma mi riduco solo a spiegare come configurare SEO su Joomla.
Andiamo sul lato administrator di Joomla. Clickiamo nel menu Sito --> Configurazione Globale. A destra della scheda dovreste vedere la sezione sotto riportata:


Come si può vedere ho attivato le prime tre opzioni.  SEF sta per Search Engine Friendly. Joomla genera i nomi degli articoli pubblicati in modo incomprensibile, tipo:
http://www.mysite.com/index.php?lang=it&Itemid=162
Tutto ciò non è ben visto dai motori di ricerca. Quindi attivando l'opzione Attiva URL SEF e Suffisso URL Joomla modificherà gli url in modo molto più comprensibile, tipo:
http://www.mysite.com/il-mio-articolo.html
In questo modo i nostri articoli sono più accessibili dai motori di ricerca.

L'opzione Riscrivi URL SEF crea unpò di problemi quando viene attivato nei server di Hosting99 oppure Aruba. Per avere il sito funzionante e nello stesso tempo anche questa opzione attivata si dovrebbe modificare il file htaccess.txt che si trova nella root di joomla. Due sono le cose da fare:
1- Commentare la riga aggiungendo # all'inizio riga: #Options +FollowSymLinks
2- Scommentare la riga togliendo # all'inizio riga: RewriteBase /

Dopo aver modificato questo file lo rinominiamo in .htaccess e abbiamo finito.