RSI-Esercitazione06 -Tomcat Sicuro +WS

Transcript

RSI-Esercitazione06 -Tomcat Sicuro +WS
Autenticazione in Tomcat per lo sviluppo di Web Service.
In questo documento si presentano i meccanismi fondamentali che consentono di accedere ai web
service secondo due livelli di sicurezza. Il primo riguarda il meccanismo di base utilizzato da
Tomcat per l’identificazione degli utenti, il secondo riguarda la comunicazione attraverso Https. Per
realizzare il primo meccanismo di autenticazione bisogna configurare il file tomcat-users.xml,
aggiungendo all’interno dei tag <tomcat-users> le righe:
<role rolename="prova"/>
<user username="prova" password="1234" roles="prova"/>
Fatto questo, dobbiamo configurare i tag Security Constraints, Login Config e Security Role nel file
web.xml di Axis, presente nella directory “Tomcat 5.5\webapps\axis\WEB-INF”. Le righe da
aggiungere sono le seguenti:
<security-constraint>
<web-resource-collection>
<web-resource-name>tutto</web-resource-name>
<url-pattern>/services/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>prova</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<description>prova</description>
<role-name>prova</role-name>
</security-role>
In questo modo abbiamo creato un controllo per l’accesso alle pagine wsdl contenute in /services.
Chi vorrà accedervi, dovrà fornire username e password definiti nel file tomcat-users.xml. Se
ritorniamo con il browser alla pagina di elenco dei files wsdl, adesso dovremmo inserire username e
password per accedere ai sorgenti:
Ovviamente andrà modificata anche la classe client che richiama ilservizio. Per fare ciò, è
sufficiente fornire username e password prima di invocare il servizio aggiungendo le seguenti righe
di codice:
call.setUsername("prova");
call.setPassword("1234");
PROTOCOLLO SSL: breve introduzione
Il protocollo SSL utilizza combinazioni di chiavi pubbliche e simmetriche. Una sessione SSL inizia
con uno scambio di messaggi effettuati nella fase detta “Handshake”. Vediamola in dettaglio.Il
server ha un certificato che descrive le informazioni riguardanti la società/ente/persona. I campi più
rilevanti sono le informazioni di cui sopra e la chiave pubblica. Il tutto è regolato dal Certificato
X.509. Tale certificato può essere garantito da una Certification Authority, la quale assicura l’esatta
corrispondenza tra il certificato e colui che lo emette. Anche il client può avere un certificato, ma
questo serve solo se esso deve ricevere dati sensibili da parte del server. Generalmente è il
contrario. Se la connessione è iniziata dal server, esso invierà al client un messaggio “server hello”.
Se è il client ad iniziare la connessione, si avrà in invio un messaggio “hello”. Analizziamo più in
dettaglio tale messaggio.
E’ definito dai campi:
1. protocol version: definisce la versione SSl usata;
2. random byte: byte casuali generati dal client;
3. Session identifier: per verificare se si tratta di una nuova sessione o di una aperta in
precedenza;
4. Lista delle CipherSuite: è una lista in cui il Client notifica al Server gli algoritmi di
crittografia supportati, ordinati in modo decrescente;
5. Lista degli algoritmi di compressione supportati dal Client.
Il Server risponde con un messaggio “server hello” definito nel modo seguente:
1. Protocol version: rappresenta la versione SSl scelta dal Server;
2. Random byte: byte generati in modo casuale;
3. Session identifier: identifica la sessione. Se non è una sessione già aperta, se ne crea una
nuova; questo nel caso in cui nel tag “session identifier” del messaggio “hello” sino presenti
tutti zeri; Altrimenti viene riesumata la sessione indicata dal client, se presente nella cache
del server;
4. ChiperSuite: famiglia di algoritmi di crittografia scelta dal server;
5. Compression method: metodo di compressione scelto da server.
Dopo questo scambio di messaggi, avviene l’autenticazione tramite lo scambio di un certificato.
Supponiamo che debba essere il server ad identificarsi. Questo vuol dire che i dati confidenziali
transiteranno dal client al server e NON viceversa, in quanto il Client non è identificato. Tale
situazione potrebbe essere, per esempio, una fase di acquisto in rete, in cui il client invia i suoi dati
personali al Server, quindi è necessario che il Server sia ben identificato. Il Server dunque invia il
certificato al Client, insieme alle preferenze riguardo l’algoritmo di crittografia da usare. A questo
punto il client verifica che il certificato ricevuto sia valido analizzando vari aspetti. Per prima cosa
la data di validità del certificato. In seguito, si verifica che la CA che garantisce il certificato
(ammesso che ce ne sia una), sia una CA affidabile. Se lo è, il client recupera la chiave pubblica
dalla sua lista di CA sicure per verificare la firma digitale arrivatagli con il certificato del server. Se
l’informazione in tale certificato è cambiata da quando è stata firmata da una CA, o se la chiave
pubblica nella lista CA non corrisponde alla chiave privata usata dalla CA per firmate il certificato
del server, il client non potrà autenticare il server. Infine, il client verifica che il nome del dominio
nel certificato server corrisponda allo stesso dominio del server. Questa fase conferma che il server
è localizzato nello stesso indirizzo di rete che è specificato nel nome di dominio del suo certificato.
Tale controllo previene attacchi del tipo “Man in the Middle”, in quanto se il domain name non
corrisponde, molto probabilmente perché il certificato è stato inviato non dal server atteso, ma da
una terza persona che si è intromessa. La connessione sarà rifiutata se i due nomi non
corrispondono. Se invece tutto è andato a buon fine, il client avrà verificato che il server è
affidabile. A questo punto il client genera una “pre master key” e la cripta con la chiave pubblica
del server. Opzionalmente, in questa fase, può essere richiesta l’autenticazione del client, che è
molto simile a quella vista prima, nel seguente modo: esso deve cifrare alcuni valori casuali
condivisi con la sua chiave privata, creando in pratica una firma. In più, il server verifica che il
client, anche se autenticato, sia autorizzato ad accedere alle risorse richieste. La chiave pubblica nel
certificato del client può facilmente convalidare tale firma se il certificato è autentico, in caso
contrario la sessione sarà terminata. Il server riceve il messaggio criptato e, verificata l’attendibiltà
del client, lo decripta tramite la sua chiave privata. Genera poi una master secret (cosa che fa anche
il client, seguendo gli stessi passi) e da questa, insieme, generano la chiave di sessione, una chiave
simmetrica che sarà usata per criptare e decriptare i dati che attraversano il tunnel SSL appena
creato; inoltre serve per verificare che i dati non vengano alterati nel lasso di tempo che intercorre
tra l’invio e la ricezione. A questo punto il client ed il server si inviano un messaggio di notifica di
HandShake concluso, e lo scambio di dati può iniziare.
Vediamo come implementare il protocollo SSL con la server authentication su Axis. Sono due le
cose da fare: crearsi un certificato e configurare Tomcat in modo che accetti connessioni SSL.
Vediamo la prima. Posizioniamoci nella directory home di Java. Adesso creeremo un keystore per il
server e lo esporteremo in un certificato chiamato server.cer. Il keystore altro non è che un
repository di certificati usato per identificare il client o il server, in questo caso il server.
Usiamo, per fare ciò, l’utility keytool di Java. Da console scriviamo:
keytool -genkey -alias server-alias -keyalg RSA -keypass changeit -storepass changeit -keystore
keystoreserver.jks
ed immettiamo le informazione riguardanti il server.
Successivamente:
keytool -export -alias server-alias -storepass changeit -file server.cer -keystore keystoreserver.jks
Il nostro certificato è pronto e possiamo visionarlo:
Da notare che, giustamente, non è considerato attendibile in quanto non è stato autenticato da una
Certification Authority.
Scorrendo il certificato possiamo visionare anche la chiave pubblica:
Il passo successivo prevede di predisporre Tomcat ad accettare connessione SSL. Apriamo il file di
configurazione di Tomcat server.xml e togliamo il simbolo di commento dalle righe relative alla
connessione SSL :
<Connector
port="8443"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="JAVA_HOME\keystoreserver.jks"
keystorePass="changeit" />
Adesso, scrivendo https://localhost:8443 , verrà visualizzato il certificato:
Se lo accettiamo, saremo in un tunnel SSL: