domenica 6 ottobre 2013

Utilizzo di certificati client SSL con PHP tra cui il certificato presente sulla Carta Nazionale dei Servizi

Utilizzo di certificati client SSL con PHP tra cui il certificato presente sulla  Carta Nazionale dei Servizi


Immaginate di visitare un qualsiasi sito web, inserire un solo pin, di essere immediatamente  loggato, automaticamente

Senza compilare nome utente e la password in un form di login.
Senza riempire il campo di OpenID e cliccando 3 volte.
Senza fare clic sul pulsante di estensione autologin del browser.
Senza un singolo cookie inviato dal browser al server.
Senza dovervi ricordare 10, 100 password per ogni servizio diverso!

So che pare fantascienza... eppure, è possibile autenticarsi e essere immediatemente autorizzato dal web server

E' possibile utilizzando i  certificati client SSL e conoscendo la struttura dei certificati di autenticazione presenti sulla Carta Nazionale dei Servizi








Un po' sulla Carta Nazionale dei servizi dal punto di vista tecnico

La Carta Nazionale dei Servizi (CNS) è uno strumento di identificazione in rete che consente la fruizione dei servizi delle amministrazioni pubbliche. La CNS non contiene la foto del titolare e non richiede particolari requisiti di sicurezza per il supporto plastico. La completa corrispondenza informatica tra CNS e CIE (Carta d'Identità Elettronica) assicura l’interoperabilità tra le due carte.
Per ulteriori approfondimenti, si veda il decreto 9 dicembre 2004 e la sezione delle specifiche tecniche.

L’elenco pubblico dei certificatori che emettono certificati CNS
In ottemperanza alle norme vigenti, DigitPA pubblica sul proprio sito l’elenco dei certificati di certificazione utilizzati per emettere certificati di autenticazione per le CNS.
Tale elenco, realizzato in conformità allo standard ETSI TS 102 231, è reso disponibile attraverso il seguente link: https://applicazioni.cnipa.gov.it/TSL/IT_TSL_CNS.xml.
Lo stesso elenco è reso disponibile in formato PDF.

 Un po' sui  certificati client

I certificati client sono, come indica il nome, installati sul client - che è il browser web - e trasferiti al server quando il server richiede loro e l'utente accetta di inviarlo.

I certificati sono emessi da un'autorità di certificazione (CA), che può essere un emittente commerciale riconosciuta come certificatore da Agenzia Digitale Italia, oppure   libera come CAcert.org , la vostra azienda o semplicemente voi stessi, grazie alla potenza dello strumento a riga di comando openssl (o un web frontend come OpenCA ).




La CA ha la responsabilità di fornire un certificato client e una chiave privata corrispondente per esso. (La normativa e l'elenco dei certtificatori riconosciti da Agenzia Digitale)
Il certificato client stesso viene inviato al server, mentre la chiave privata viene utilizzata per firmare la richiesta.
 Questa firma viene verificata sul lato server, in modo che il server sa che sei davvero quello che il certificato appartiene.

Si noti che il certificato client può essere utilizzato solo quando si accede al server con HTTPS (HTTP over SSL-TLS).

I certificati hanno una data di scadenza, dopo la quale non sono più validi e devono essere rinnovati
Quando si implementa il controllo di accesso, dobbiamo tenerne conto.


Lato server

Il server Web deve essere configurato per HTTPS, il che significa che avete bisogno di un certificato server SSL.
Prima di utilizzare un certificato clinet occorre che il server presenti il proprio certificato quindi vedremo come si ottiene e si istalla un certificato server side.

In primo luogo, generare un Certificate Signing Request con il generatore di CSR (http://wiki.cacert.org/CSRGenerator).

 Memorizzare il file contente la chiave sotto
  / Etc / ssl / private / mioserver.lucabonuccelli.it.key

Utilizzare il quindi file. Csr e l'interfaccia web CAcert per generare un certificato firmato. Conservarlo come

  / Etc / ssl / private / mioserver.lucabonuccelli.it-cacert.pem

Ora andare a prendere entrambi i certificati ufficiali CAcert (root e di classe 3) e mettere entrambi insieme in

  / Etc/ssl/private/cacert-1and3.crt

Configurazione del server

Una configurazione dell'host virtuale di base con SSL si presenta così:

     ServerName mioserver.lucabonuccelli.it

     LogFormat "% V% h% l% u% t \"% r \ "% s% b" vcommon
     CustomLog / var/log/apache2/access_log vcommon

     VirtualDocumentRoot / home / cweiske / Dev / html / hosts / mioserver.lucabonuccelli.it
   
         AllowOverride all
   
     SSLEngine On
     SSLCertificateFile / etc / ssl / private / mioserver.lucabonuccelli.it-cacert.pem
     SSLCertificateKeyFile / etc / ssl / private / mioserver.lucabonuccelli.it.key
     SSLCACertificateFile / etc/ssl/private/cacert-1and3.crt
  ]

Oltre  questo, potrebbe essere necessario attivare il modulo SSL nel vostro server web, cioè eseguendo

  $ A2enmod ssl

Riavviare il server HTTP. Si dovrebbe essere in grado di richiedere le pagine tramite HTTPS ora.


Impostare la richiesta del certificto client da parte del server


Di default un server Web non richiede alcun tipo di certificato client occorre attivare questa funzione

Il client certs può essere obbligatorio (in assenza il server non accetta la request) o opzionale , cosa che premette di consentire agli utenti un  login "classic"o  tramite username / password o con certificati SSL.


Occorre quindi inserire le seguenti direttive all'interno del virtual host:

     SSLVerifyClient optional
     SSLVerifyDepth 3
     SSLOptions + StdEnvVars

 
Ci sono diverse opzioni è necessario impostare:

SSLVerifyClient optional


    Potete scegliere "opzionale" o  "obbligatorio" (mandatary).
    Opzionale chiede il browser per un certificato client ma accetta la request se il browser (l'utente) non scegliere di non inviare alcun certificato.
    Questa è la migliore opzione se si vuole essere in grado di accedere con e senza un certificato.

    L'impostazione "obbligatorio" (mandatary) istruisce il server web affinchè termini  la connessione quando nessun certificato client viene inviato dal browser.
    Questa opzione può essere utilizzata quando tutti gli utenti hanno il loro set certificato client oppure qundo si vuole offrire un servizio con un livello di sicurezza ben superiore all tipoco "login e password"

   SSLVerifyDepth 3

    Il certificato client è firmato da un'autorità di certificazione (CA), e il server Web si fida della CA specificata nella SSLCACertificateFile. Può accadere che il nostro certificato clinet sia firmato da  delle CA "intermedie" che (firmate dalla CA principale),

      CAcert >> proprio CA >> il certificato client

    In questo caso, si ha una profondità maggiore. Per la maggior parte dei casi, è sufficiente 1, se però si vuole utilizzare come certificato client i certificato presenti in smart card rilasciateda CA ufficiali occorre talvolta aumentare il valore  di default.

SSLOptions + StdEnvVars


    Questa direttiva istruisce il vostro server web affinchè inoltro  le variabili di ambiente SSL a PHP, in modo che l'applicazione possa rilevare che un certificato client è disponibile e leggere i dati.

    Nel caso in cui è necessario il certificato client completo, dovete aggiungere + ExportCertData alla linea.
    cosa che moltiplica la dimensione dei dati scambiati tra il web server e PHP, che è per questo che è disattivata la maggior parte delle volte.

Se si riavvia il web server ora, questi  richiederà un certificato client.

Può accadere che il browser non faccia apparire la finestra di selezione certificati. questo è dovuto al fatto che il web server invia un elenco delle CA che ritiene valida al browser. Se il browser non dispone di un certificato da una di quelle CA, non visualizzare il popup.



L'aggiunta del supporto certificato client per l'applicazione PHP



Accesso ai dati del certificato


Quando un certificato client è disponibile, la variabile $_SERVER contiene una serie di variabili SSL_CLIENT_ * .

La variabile $_SERVER ['SSL_CLIENT_VERIFY'] è importante.
Non utilizzare il certificato se la verifica non ha avuto successo! (VALORE = SUCCESS).
Quando nessun certificato viene passato, la funzione restuituisce NONE.

Un'altra variabile importante è SSL_CLIENT_M_SERIAL che indica  il seriale che identifica in modo univoco un certificato da una certa autorità di certificazione.

Tutte le variabili con SSL_CLIENT_I_ *  riguardano l'emittente, mentre è la CA.
SSL_CLIENT_S_ *  riguardano  il "soggetto", l'utente che ha inviato il certificato client.

SSL_CLIENT_S_DN_CN per esempio contiene il "common name" dell'utente .


Identificazione del Certificato


Associazione di un account utente con un certificato client è brutalmente possibile solo consentendo + ExportCertData e memorizzando il certificato client nel database utente.
Questo è un male per due motivi:

  • Se il certificato scade e viene rinnovata, l'utente non può accedere più.
  • È necessario passare più dati per ogni processo di PHP e di memorizzare più dati del necessario nel database utente.

Secondo  le regole italiane, se si accettano solo le CA riconoscite da Agenzia Digitale Italia il "Common Name" e si utilizzano certificati conformi alla Carta Nazionale dei Servizi è composto dalla concatenzazione di

codicefiscale/nome/cognome/altri dati

Quindi assumiamo di basarci sul codice fiscale di un soggetto per riconoscerlo.
è sufficiente questo codice php:

  • più.



  • È necessario passare più dati per ogni processo di PHP e di memori

  • $cf = $_SERVER['SSL_CLIENT_S_DN_CN'];
    if ($cf){
    $cf=substr($cf, 0, 16);
    }



    Controlli OCSP


    L'Online Certificate Status Protocol (OCSP) consente di verificare se il certificato è stato revocato dalla CA.
    La revoca avviene se la sicurezza del certificato è stata compromessa in qualche modo, oppure potrebbe essere rubato.

    Apache dalla versione 2.3 è in grado di fare la OCSP in autonomia  se si attiva l'opzione  SSLOCSPEnable.

    Bibliografia /link


      

    Nessun commento:

    Posta un commento

    FeedBurner FeedCount