Lezione 5: Socket SSL/
             TLS
        Corso di Programmazione in Rete
       Laurea Magistrale in Ing. Informatica
         Università degli Studi di Salerno



1
Outline


    ✦ Introduzione

    ✦ Gestione delle chiavi e dei certificati

    ✦ Comunicazione con socket SSL/TLS




2
Introduzione

    ✦ Mentre per applicazioni limitate a una
      rete locale si può assumere che il
      contesto sia “amichevole”, l’arrivo di
      Internet rende necessarie considerazioni
      sulla sicurezza della comunicazione
     •   autenticazione dell’altro end-point con cui si
         comunica
     •   riservatezza dei dati scambiati



3
Crittografia

    ✦ Le esigenze di sicurezza si risolvono
      adottando algoritmi di crittografia per
      proteggere le comunicazioni
    ✦ In particolare, la crittografia a chiave
      pubblica (detta anche a chiave
      asimmetrica) consente l’autenticazione
      dell’altro end-point senza il problema
      della condivisione della chiave


4
Crittografia a chiave pubblica

    ✦ Ciascuno dei due end-point genera due
      chiavi:
     •   una chiave privata, che deve essere nota solo al
         proprietario
     •   una chiave pubblica, che deve essere resa nota
         all’altro end-point
    ✦ I dati codificati con una chiave privata
      possono essere decodificati solo con la
      corrispondente chiave pubblica e
      viceversa

5
Crittografia a chiave pubblica

    ✦ Il mittente codifica due volte
      l’informazione:
     •   con la propria chiave privata
     •   con la chiave pubblica del destinatario
    ✦ Il destinatario deve effettuare una doppia
      decodifica per leggere l’informazione:
     •   con la propria chiave privata
     •   con la chiave pubblica del mittente



6
Crittografia a chiave pubblica

    ✦ Il mittente è certo che solo il destinatario
      leggerà i dati, perché è necessaria la
      chiave privata del destinatario per la
      decodifica (riservatezza)
    ✦ Il destinatario è certo che i dati sono stati
      inviati dal mittente, perché è necessaria
      la chiave privata del mittente per la
      codifica (autenticazione)


7
Crittografia a chiave pubblica

    ✦ In pratica, per motivi prestazionali, il
      client e il server usano questa tecnica per
      scambiarsi una chiave simmetrica in
      modo sicuro e poi passano a un algoritmo
      di crittografia tradizionale
    ✦ Spesso è necessaria la sola
      autenticazione del server; in tal caso solo
      il server ha una coppia di chiavi, e il client
      deve avere la chiave pubblica del server

8
Certificati
    ✦ Per evitare la necessità di scambiare in
      anticipo in modo sicuro le chiavi
      pubbliche, si usano certificati
    ✦ Un certificato contiene una chiave
      pubblica autenticata mediante la firma
      digitale di una Certification Authority (CA)
    ✦ Chi riceve il certificato può verificare
      direttamente l’autenticità della chiave
      pubblica usando la chiave pubblica della
      CA (che deve essere nota)
9
SSL/TLS
     ✦ I protocolli di Internet (TCP/UDP/IP) non
       offrivano inizialmente nessun supporto
       alla crittografia, che doveva essere
       realizzata a livello applicazione
     ✦ Nel 1995 Netscape propose un protocollo
       denominato Socket Security Layer (SSL)
       per rendere sicuro il web attraverso l’uso
       di crittografia a chiave pubblica
     ✦ Successivamente l’IETF ha recepito il
       protocollo come base per lo standard
       Transport Layer Security (TLS)
10
SSL/TLS

     ✦ Implementati a livello applicazione
       (nonostante il nome) mediante librerie
       (anche Open Source)
     ✦ Usati per incapsulare altri protocolli di
       livello applicazione (es. HTTP, SMTP etc.)
       in modo da renderli “sicuri”



11
Gestione delle chiavi e dei certificati
     ✦ Il Java Development Kit include un tool
       (da usare a linea di comando) per gestire
       chiavi e certificati: keytool
     ✦ Le chiavi pubbliche e private sono
       memorizzate in un keystore
     ✦ I certificati ritenuti “fidati” sono
       memorizzati in un truststore
     ✦ Il formato del keystore e del truststore è
       proprietario, ma keytool offre funzioni per
       import/export di chiavi e certificati nei
       formati dello standard X.509
12
Generazione delle chiavi
     ✦ Per generare una coppia di chiavi in un
       keystore il comando è:
      •   keytool -genkey [opz...] -alias nome
                  -validity giorni -keystore keystore
     ✦ Il tool richiede alcune informazioni
       sull’identità della persona che genera le
       chiavi, che saranno memorizzate
       all’interno delle chiavi stesse
     ✦ Il keystore è protetto da una password

13
Generazione delle chiavi
     ✦ Esempio
      foggia% keytool -genkey -alias foggia -validity 365 -keystore keystore.jks
      Immettere la password del keystore: pippobaudo
      Specificare nome e cognome
       [Unknown]: Pasquale Foggia
      Specificare il nome dell'unit? aziendale
       [Unknown]: diiie
      Specificare il nome dell'azienda
       [Unknown]: unisa
      Specificare la localit?
       [Unknown]: fisciano
      Specificare la provincia
       [Unknown]: sa
      Specificare il codice a due lettere del paese in cui si trova l'unit?
       [Unknown]: it
      Il dato CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa, C=it ?
      corretto?
       [no]: s

      Immettere la password della chiave per <foggia>
      	    (INVIO se corrisponde alla password del keystore):
      foggia%




14
Generazione delle chiavi
     ✦ È possibile visualizzare il contenuto di un
       keystore con il comando:
      •   keytool -list -v -keystore keystore
          foggia% keytool -list -v -keystore keystore.jks
          Immettere la password del keystore: pippobaudo

          Tipo keystore: jks
          Provider keystore: SUN

          Il keystore contiene 1 entry

          Nome alias: foggia
          Data di creazione: 31-mar-2009
          Tipo entry: keyEntry
          Lunghezza catena certificati: 1
          Certificato[1]:
          Proprietario: CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa, C=it
          Organismo di emissione: CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano,
          ST=sa, C=it
          Numero di serie: 49d1e411
          Valido da Tue Mar 31 11:36:17 CEST 2009 a Wed Mar 31 11:36:17 CEST 2010
          Impronte digitali certificato:
          	     MD5: 58:A9:4F:D3:31:E9:C1:58:E3:75:5C:90:85:8D:81:13
          	     SHA1: C1:20:ED:DC:43:14:00:F3:50:ED:07:15:D2:0A:93:B2:5C:38:21:B1

15
Generazione di certificati

     ✦ In genere il processo per generare un
       certificato richiede tre passi:
      •   creazione di una Certificate Request a partire
          dalla chiave pubblica nel keystore
      •   invio della Certificate Request alla CA, che
          produce il certificato
      •   importazione del certificato della CA nel truststore




16
Generazione di certificati
     ✦ Non avendo a disposizione una CA,
       genereremo un self-signed certificate
      •   non c’è la garanzia sull’identità data dalla CA
      •   adeguato se i due end-point si fidano
          reciprocamente e possono scambiarsi i certificati
          in maniera sicura
     ✦ I passi diventano:
      •   generazione del certificato dalla chiave pubblica
          nel keystore
      •   importazione del certificato nel truststore


17
Generazione di certificati
     ✦ Per generare il certificato, il comando è:
      •   keytool -export -alias nome -keystore keystore
                  -rfc -file filecert
          foggia% keytool -export -alias foggia -keystore keystore.jks -rfc -file foggia.cer
          Immettere la password del keystore: pippobaudo
          Il certificato ? memorizzato nel file <foggia.cer>
          foggia%
          foggia% cat foggia.cer
          -----BEGIN CERTIFICATE-----
          MIIDAjCCAsACBEnR5BEwCwYHKoZIzjgEAwUAMGcxCzAJBgNVBAYTAml0MQswCQYDVQQIEwJzYTER
          MA8GA1UEBxMIZmlzY2lhbm8xDjAMBgNVBAoTBXVuaXNhMQ4wDAYDVQQLEwVkaWlpZTEYMBYGA1UE
          AxMPUGFzcXVhbGUgRm9nZ2lhMB4XDTA5MDMzMTA5MzYxN1oXDTEwMDMzMTA5MzYxN1owZzELMAkG
          A1UEBhMCaXQxCzAJBgNVBAgTAnNhMREwDwYDVQQHEwhmaXNjaWFubzEOMAwGA1UEChMFdW5pc2Ex
          DjAMBgNVBAsTBWRpaWllMRgwFgYDVQQDEw9QYXNxdWFsZSBGb2dnaWEwggG3MIIBLAYHKoZIzjgE
          ATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow
          9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVU
          E1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps9
          3su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbh
          PBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVk
          AUw7/s9JKgOBhAACgYAwr9DQG3MVcFIPlzTr5yyAfn28J2PvzAQp9Eft84hLr7d9vGaSFY4vHrx0
          eCacuvouvBc6BzQo5H6CrbbeRaQQIGD5dTwORjI4qDWKZDNVL8EeEhTNLrsMb55jDNuw/epyHz6A
          /Fdz6/QgYp3bEYRTwwoIf4YJusTrzC500Ip2cjALBgcqhkjOOAQDBQADLwAwLAIULlNtybkWx9nm
          /yq0S3iW+AD4DvoCFHzBQCW9J/4qPGgfOpPaF43pt9In
          -----END CERTIFICATE-----

18
Generazione di certificati
     ✦ Per importare il certificato, il comando è:
      •   keytool -import -alias nome -keystore truststore
                  -file filecert
          foggia% keytool -import -alias foggiacert -keystore truststore.jks -file foggia.cer
          Immettere la password del keystore: pippobaudo
          Proprietario: CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa, C=it
          Organismo di emissione: CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa,
          C=it
          Numero di serie: 49d1e411
          Valido da Tue Mar 31 11:36:17 CEST 2009 a Wed Mar 31 11:36:17 CEST 2010
          Impronte digitali certificato:
          	     MD5: 58:A9:4F:D3:31:E9:C1:58:E3:75:5C:90:85:8D:81:13
          	     SHA1: C1:20:ED:DC:43:14:00:F3:50:ED:07:15:D2:0A:93:B2:5C:38:21:B1
          Considerare attendibile questo certificato? [no]: s
          Il certificato ? stato aggiunto al keystore
          foggia%
          foggia% keytool -list -keystore truststore.jks
          Immettere la password del keystore: pippobaudo

          Tipo keystore: jks
          Provider keystore: SUN

          Il keystore contiene 1 entry

          foggiacert, 31-mar-2009, trustedCertEntry,
          Impronta digitale certificato (MD5): 58:A9:4F:D3:31:E9:C1:58:E3:75:5C:90:85:8D:81:13
19
Comunicazione con Socket SSL/TLS

     ✦ In Java l’uso di SSL/TLS si basa sulle
       classi SSLSocket e SSLServerSocket, che
       estendono rispettivamente Socket e
       ServerSocket
     ✦ Una volta effettuata la creazione dei
       socket, non c’è differenza per
       l’applicazione rispetto all’uso di socket
       non crittografati


20
Creazione di socket SSL

     ✦ Le classi e le interfacce necessarie sono
       nei package:
      •   javax.net.*
      •   javax.net.ssl.*
     ✦ Il primo passo è la creazione di una
       SocketFactory, che è un oggetto che
       astrae l’operazione di creazione di un
       socket


21
Creazione di un socket SSL
     ✦ Per creare una SocketFactory in grado di
       creare Socket SSL occorre usare il
       metodo static getDefault() della classe
       SSLSocketFactory


       SocketFactory factory=SSLSocketFactory.getDefault();




22
Creazione di un socket SSL
     ✦ Una volta ottenuta una factory, si può
       usare il metodo createSocket() per creare
       il socket vero e proprio:


         Socket sock=factory.createSocket(host, port);




     ✦ Una volta creato, il socket si usa come un
       normale client socket
23
Keystore e truststore

     ✦ Per rendere possibile la creazione del
       socket SSL, il programma deve conoscere
       il keystore e il truststore e le relative
       password
     ✦ È possibile fornire tali informazioni
       usando opportune proprietà di sistema



24
Keystore e truststore
       ✦ Le proprietà di sistema possono essere
         impostate con il metodo
         System.setProperty():

     System.setProperty("javax.net.ssl.keyStore", "clientkeystore.jks");
     System.setProperty("javax.net.ssl.keyStorePassword", "pippobaudo");
     System.setProperty("javax.net.ssl.trustStore",
                        "clienttruststore.jks");
     System.setProperty("javax.net.ssl.trustStorePassword",
                        "pippobaudo");




25
Creazione di Server Socket

     ✦ La creazione di server socket SSL è
       analoga alla creazione di socket
     ✦ Occorre usare le classi:
      •   ServerSocketFactory
      •   SSLServerSocketFactory
      •   SSLServerSocket




26
Creazione di Server Socket
       ✦ Esempio:

     ServerSocketFactory factory=SSLServerSocketFactory.getDefault();
     ServerSocket sock=factory.createServerSocket(port);




     ✦ Una volta creato, il server socket si usa
       esattamente come un ServerSocket non
       crittografato
     ✦ Il keystore e il truststore devono essere
       specificati con le stesse proprietà di
27
       sistema
Creazione di Server Socket
       ✦ Per default i socket creati dalla factory
         effettuano l’autenticazione del solo server
       ✦ Se si desidera l’autenticazione anche del
         client, occorre convertire il socket in un
         SSLServerSocket e richiamare il metodo
         setNeedClientAuth()

     ServerSocketFactory factory=SSLServerSocketFactory.getDefault();
     SSLServerSocket sock=(SSLServerSocket)
                              factory.createServerSocket(port);
     sock.setNeedClientAuth(true);



28
Un client completo
     import   java.io.*;
     import   java.net.*;
     import   javax.net.*;
     import   javax.net.ssl.*;

     public class SSLEchoClient {
     	 public static final int PORT=7777;
     	
     	 public static Socket createSocket(String host, int port) throws IOException {
     	 	 SocketFactory factory=SSLSocketFactory.getDefault();
     	 	 Socket sock=factory.createSocket(host, port);
     	 	 return sock;
     	 }

        // continua ...




29
Un client completo
     	   public static void main(String args[]) throws IOException {
     	   	 System.setProperty("javax.net.ssl.keyStore", "clientkeystore.jks");
     	   	 System.setProperty("javax.net.ssl.keyStorePassword", "pippobaudo");
     	   	 System.setProperty("javax.net.ssl.trustStore", "clienttruststore.jks");
     	   	 System.setProperty("javax.net.ssl.trustStorePassword", "pippobaudo");

     	   	   Socket sock=createSocket(args[0], PORT);
     	   	   OutputStream os=sock.getOutputStream();
     	   	   Writer wr=new OutputStreamWriter(os, "UTF-8");
     	   	   PrintWriter prw=new PrintWriter(wr);
     	   	   prw.println("Hello, world");
     	   	   prw.flush();
     	   	
     	   	   InputStream is=sock.getInputStream();
     	   	   Reader rd=new InputStreamReader(is, "UTF-8");
     	   	   BufferedReader brd=new BufferedReader(rd);
     	   	   String answer=brd.readLine();
     	   	   System.out.println(answer);
     	   	
     	   	   sock.close();
     	   }
     }



30
Un server completo
     import   java.io.*;
     import   java.net.*;
     import   javax.net.*;
     import   javax.net.ssl.*;

     public class SSLEchoServer implements Runnable {
     	 public static final int PORT=7777;
     	
     	 private Socket sock;
     	
     	 public SSLEchoServer(Socket s) {
     	 	 sock=s;
     	 }
     	
     	 public static ServerSocket createServerSocket(int port) throws IOException {
     	 	 ServerSocketFactory factory=SSLServerSocketFactory.getDefault();
     	 	 SSLServerSocket sock=(SSLServerSocket) factory.createServerSocket(port);
     	 	 sock.setNeedClientAuth(true);
     	 	 return sock;
     	 }
        // continua ...



31
Un server completo

     	   public static void main(String args[]) throws IOException {
     	   	 System.setProperty("javax.net.ssl.keyStore", "servkeystore.jks");
     	   	 System.setProperty("javax.net.ssl.keyStorePassword", "pippobaudo");
     	   	 System.setProperty("javax.net.ssl.trustStore", "servtruststore.jks");
     	   	 System.setProperty("javax.net.ssl.trustStorePassword", "pippobaudo");
     	
     	   	 ServerSocket serv=createServerSocket(PORT);
     	   	 while (true) {
     	   	 	 Socket sock=serv.accept();
     	   	 	 SSLEchoServer server=new SSLEchoServer(sock);
     	   	 	 Thread t=new Thread(server);
     	   	 	 t.start();
     	   	 }
     	   }
         // continua...




32
Un server completo
     	   public void run() {
     	   	 try {
     	   	 	 BufferedReader brd=new BufferedReader(
     	   	 	 	 	 new InputStreamReader(
     	   	 	 	 	 	 	 sock.getInputStream(), "UTF-8"));
     	   	 	 String s=brd.readLine();
     	   	 	
     	   	 	 PrintWriter prw=new PrintWriter(
     	   	 	 	 	 new OutputStreamWriter(
     	   	 	 	 	 	 	 sock.getOutputStream(), "UTF-8"));
     	   	 	 prw.print(s);
     	   	 	 prw.println(s);
     	   	 	 prw.flush();
     	   	 } catch (IOException exc) {
     	   	 	 System.out.println("Eccezione I/O:" + exc);
     	   	 	 exc.printStackTrace();
     	   	 } finally {
     	   	 	 try { sock.close(); }
     	   	 	 catch (IOException exc2) { }
     	   	 }
     	   }
     }



33

Lezione 5: Socket SSL/ TLS

  • 1.
    Lezione 5: SocketSSL/ TLS Corso di Programmazione in Rete Laurea Magistrale in Ing. Informatica Università degli Studi di Salerno 1
  • 2.
    Outline ✦ Introduzione ✦ Gestione delle chiavi e dei certificati ✦ Comunicazione con socket SSL/TLS 2
  • 3.
    Introduzione ✦ Mentre per applicazioni limitate a una rete locale si può assumere che il contesto sia “amichevole”, l’arrivo di Internet rende necessarie considerazioni sulla sicurezza della comunicazione • autenticazione dell’altro end-point con cui si comunica • riservatezza dei dati scambiati 3
  • 4.
    Crittografia ✦ Le esigenze di sicurezza si risolvono adottando algoritmi di crittografia per proteggere le comunicazioni ✦ In particolare, la crittografia a chiave pubblica (detta anche a chiave asimmetrica) consente l’autenticazione dell’altro end-point senza il problema della condivisione della chiave 4
  • 5.
    Crittografia a chiavepubblica ✦ Ciascuno dei due end-point genera due chiavi: • una chiave privata, che deve essere nota solo al proprietario • una chiave pubblica, che deve essere resa nota all’altro end-point ✦ I dati codificati con una chiave privata possono essere decodificati solo con la corrispondente chiave pubblica e viceversa 5
  • 6.
    Crittografia a chiavepubblica ✦ Il mittente codifica due volte l’informazione: • con la propria chiave privata • con la chiave pubblica del destinatario ✦ Il destinatario deve effettuare una doppia decodifica per leggere l’informazione: • con la propria chiave privata • con la chiave pubblica del mittente 6
  • 7.
    Crittografia a chiavepubblica ✦ Il mittente è certo che solo il destinatario leggerà i dati, perché è necessaria la chiave privata del destinatario per la decodifica (riservatezza) ✦ Il destinatario è certo che i dati sono stati inviati dal mittente, perché è necessaria la chiave privata del mittente per la codifica (autenticazione) 7
  • 8.
    Crittografia a chiavepubblica ✦ In pratica, per motivi prestazionali, il client e il server usano questa tecnica per scambiarsi una chiave simmetrica in modo sicuro e poi passano a un algoritmo di crittografia tradizionale ✦ Spesso è necessaria la sola autenticazione del server; in tal caso solo il server ha una coppia di chiavi, e il client deve avere la chiave pubblica del server 8
  • 9.
    Certificati ✦ Per evitare la necessità di scambiare in anticipo in modo sicuro le chiavi pubbliche, si usano certificati ✦ Un certificato contiene una chiave pubblica autenticata mediante la firma digitale di una Certification Authority (CA) ✦ Chi riceve il certificato può verificare direttamente l’autenticità della chiave pubblica usando la chiave pubblica della CA (che deve essere nota) 9
  • 10.
    SSL/TLS ✦ I protocolli di Internet (TCP/UDP/IP) non offrivano inizialmente nessun supporto alla crittografia, che doveva essere realizzata a livello applicazione ✦ Nel 1995 Netscape propose un protocollo denominato Socket Security Layer (SSL) per rendere sicuro il web attraverso l’uso di crittografia a chiave pubblica ✦ Successivamente l’IETF ha recepito il protocollo come base per lo standard Transport Layer Security (TLS) 10
  • 11.
    SSL/TLS ✦ Implementati a livello applicazione (nonostante il nome) mediante librerie (anche Open Source) ✦ Usati per incapsulare altri protocolli di livello applicazione (es. HTTP, SMTP etc.) in modo da renderli “sicuri” 11
  • 12.
    Gestione delle chiavie dei certificati ✦ Il Java Development Kit include un tool (da usare a linea di comando) per gestire chiavi e certificati: keytool ✦ Le chiavi pubbliche e private sono memorizzate in un keystore ✦ I certificati ritenuti “fidati” sono memorizzati in un truststore ✦ Il formato del keystore e del truststore è proprietario, ma keytool offre funzioni per import/export di chiavi e certificati nei formati dello standard X.509 12
  • 13.
    Generazione delle chiavi ✦ Per generare una coppia di chiavi in un keystore il comando è: • keytool -genkey [opz...] -alias nome -validity giorni -keystore keystore ✦ Il tool richiede alcune informazioni sull’identità della persona che genera le chiavi, che saranno memorizzate all’interno delle chiavi stesse ✦ Il keystore è protetto da una password 13
  • 14.
    Generazione delle chiavi ✦ Esempio foggia% keytool -genkey -alias foggia -validity 365 -keystore keystore.jks Immettere la password del keystore: pippobaudo Specificare nome e cognome [Unknown]: Pasquale Foggia Specificare il nome dell'unit? aziendale [Unknown]: diiie Specificare il nome dell'azienda [Unknown]: unisa Specificare la localit? [Unknown]: fisciano Specificare la provincia [Unknown]: sa Specificare il codice a due lettere del paese in cui si trova l'unit? [Unknown]: it Il dato CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa, C=it ? corretto? [no]: s Immettere la password della chiave per <foggia> (INVIO se corrisponde alla password del keystore): foggia% 14
  • 15.
    Generazione delle chiavi ✦ È possibile visualizzare il contenuto di un keystore con il comando: • keytool -list -v -keystore keystore foggia% keytool -list -v -keystore keystore.jks Immettere la password del keystore: pippobaudo Tipo keystore: jks Provider keystore: SUN Il keystore contiene 1 entry Nome alias: foggia Data di creazione: 31-mar-2009 Tipo entry: keyEntry Lunghezza catena certificati: 1 Certificato[1]: Proprietario: CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa, C=it Organismo di emissione: CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa, C=it Numero di serie: 49d1e411 Valido da Tue Mar 31 11:36:17 CEST 2009 a Wed Mar 31 11:36:17 CEST 2010 Impronte digitali certificato: MD5: 58:A9:4F:D3:31:E9:C1:58:E3:75:5C:90:85:8D:81:13 SHA1: C1:20:ED:DC:43:14:00:F3:50:ED:07:15:D2:0A:93:B2:5C:38:21:B1 15
  • 16.
    Generazione di certificati ✦ In genere il processo per generare un certificato richiede tre passi: • creazione di una Certificate Request a partire dalla chiave pubblica nel keystore • invio della Certificate Request alla CA, che produce il certificato • importazione del certificato della CA nel truststore 16
  • 17.
    Generazione di certificati ✦ Non avendo a disposizione una CA, genereremo un self-signed certificate • non c’è la garanzia sull’identità data dalla CA • adeguato se i due end-point si fidano reciprocamente e possono scambiarsi i certificati in maniera sicura ✦ I passi diventano: • generazione del certificato dalla chiave pubblica nel keystore • importazione del certificato nel truststore 17
  • 18.
    Generazione di certificati ✦ Per generare il certificato, il comando è: • keytool -export -alias nome -keystore keystore -rfc -file filecert foggia% keytool -export -alias foggia -keystore keystore.jks -rfc -file foggia.cer Immettere la password del keystore: pippobaudo Il certificato ? memorizzato nel file <foggia.cer> foggia% foggia% cat foggia.cer -----BEGIN CERTIFICATE----- MIIDAjCCAsACBEnR5BEwCwYHKoZIzjgEAwUAMGcxCzAJBgNVBAYTAml0MQswCQYDVQQIEwJzYTER MA8GA1UEBxMIZmlzY2lhbm8xDjAMBgNVBAoTBXVuaXNhMQ4wDAYDVQQLEwVkaWlpZTEYMBYGA1UE AxMPUGFzcXVhbGUgRm9nZ2lhMB4XDTA5MDMzMTA5MzYxN1oXDTEwMDMzMTA5MzYxN1owZzELMAkG A1UEBhMCaXQxCzAJBgNVBAgTAnNhMREwDwYDVQQHEwhmaXNjaWFubzEOMAwGA1UEChMFdW5pc2Ex DjAMBgNVBAsTBWRpaWllMRgwFgYDVQQDEw9QYXNxdWFsZSBGb2dnaWEwggG3MIIBLAYHKoZIzjgE ATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow 9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVU E1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps9 3su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbh PBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVk AUw7/s9JKgOBhAACgYAwr9DQG3MVcFIPlzTr5yyAfn28J2PvzAQp9Eft84hLr7d9vGaSFY4vHrx0 eCacuvouvBc6BzQo5H6CrbbeRaQQIGD5dTwORjI4qDWKZDNVL8EeEhTNLrsMb55jDNuw/epyHz6A /Fdz6/QgYp3bEYRTwwoIf4YJusTrzC500Ip2cjALBgcqhkjOOAQDBQADLwAwLAIULlNtybkWx9nm /yq0S3iW+AD4DvoCFHzBQCW9J/4qPGgfOpPaF43pt9In -----END CERTIFICATE----- 18
  • 19.
    Generazione di certificati ✦ Per importare il certificato, il comando è: • keytool -import -alias nome -keystore truststore -file filecert foggia% keytool -import -alias foggiacert -keystore truststore.jks -file foggia.cer Immettere la password del keystore: pippobaudo Proprietario: CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa, C=it Organismo di emissione: CN=Pasquale Foggia, OU=diiie, O=unisa, L=fisciano, ST=sa, C=it Numero di serie: 49d1e411 Valido da Tue Mar 31 11:36:17 CEST 2009 a Wed Mar 31 11:36:17 CEST 2010 Impronte digitali certificato: MD5: 58:A9:4F:D3:31:E9:C1:58:E3:75:5C:90:85:8D:81:13 SHA1: C1:20:ED:DC:43:14:00:F3:50:ED:07:15:D2:0A:93:B2:5C:38:21:B1 Considerare attendibile questo certificato? [no]: s Il certificato ? stato aggiunto al keystore foggia% foggia% keytool -list -keystore truststore.jks Immettere la password del keystore: pippobaudo Tipo keystore: jks Provider keystore: SUN Il keystore contiene 1 entry foggiacert, 31-mar-2009, trustedCertEntry, Impronta digitale certificato (MD5): 58:A9:4F:D3:31:E9:C1:58:E3:75:5C:90:85:8D:81:13 19
  • 20.
    Comunicazione con SocketSSL/TLS ✦ In Java l’uso di SSL/TLS si basa sulle classi SSLSocket e SSLServerSocket, che estendono rispettivamente Socket e ServerSocket ✦ Una volta effettuata la creazione dei socket, non c’è differenza per l’applicazione rispetto all’uso di socket non crittografati 20
  • 21.
    Creazione di socketSSL ✦ Le classi e le interfacce necessarie sono nei package: • javax.net.* • javax.net.ssl.* ✦ Il primo passo è la creazione di una SocketFactory, che è un oggetto che astrae l’operazione di creazione di un socket 21
  • 22.
    Creazione di unsocket SSL ✦ Per creare una SocketFactory in grado di creare Socket SSL occorre usare il metodo static getDefault() della classe SSLSocketFactory SocketFactory factory=SSLSocketFactory.getDefault(); 22
  • 23.
    Creazione di unsocket SSL ✦ Una volta ottenuta una factory, si può usare il metodo createSocket() per creare il socket vero e proprio: Socket sock=factory.createSocket(host, port); ✦ Una volta creato, il socket si usa come un normale client socket 23
  • 24.
    Keystore e truststore ✦ Per rendere possibile la creazione del socket SSL, il programma deve conoscere il keystore e il truststore e le relative password ✦ È possibile fornire tali informazioni usando opportune proprietà di sistema 24
  • 25.
    Keystore e truststore ✦ Le proprietà di sistema possono essere impostate con il metodo System.setProperty(): System.setProperty("javax.net.ssl.keyStore", "clientkeystore.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "pippobaudo"); System.setProperty("javax.net.ssl.trustStore", "clienttruststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "pippobaudo"); 25
  • 26.
    Creazione di ServerSocket ✦ La creazione di server socket SSL è analoga alla creazione di socket ✦ Occorre usare le classi: • ServerSocketFactory • SSLServerSocketFactory • SSLServerSocket 26
  • 27.
    Creazione di ServerSocket ✦ Esempio: ServerSocketFactory factory=SSLServerSocketFactory.getDefault(); ServerSocket sock=factory.createServerSocket(port); ✦ Una volta creato, il server socket si usa esattamente come un ServerSocket non crittografato ✦ Il keystore e il truststore devono essere specificati con le stesse proprietà di 27 sistema
  • 28.
    Creazione di ServerSocket ✦ Per default i socket creati dalla factory effettuano l’autenticazione del solo server ✦ Se si desidera l’autenticazione anche del client, occorre convertire il socket in un SSLServerSocket e richiamare il metodo setNeedClientAuth() ServerSocketFactory factory=SSLServerSocketFactory.getDefault(); SSLServerSocket sock=(SSLServerSocket) factory.createServerSocket(port); sock.setNeedClientAuth(true); 28
  • 29.
    Un client completo import java.io.*; import java.net.*; import javax.net.*; import javax.net.ssl.*; public class SSLEchoClient { public static final int PORT=7777; public static Socket createSocket(String host, int port) throws IOException { SocketFactory factory=SSLSocketFactory.getDefault(); Socket sock=factory.createSocket(host, port); return sock; } // continua ... 29
  • 30.
    Un client completo public static void main(String args[]) throws IOException { System.setProperty("javax.net.ssl.keyStore", "clientkeystore.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "pippobaudo"); System.setProperty("javax.net.ssl.trustStore", "clienttruststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "pippobaudo"); Socket sock=createSocket(args[0], PORT); OutputStream os=sock.getOutputStream(); Writer wr=new OutputStreamWriter(os, "UTF-8"); PrintWriter prw=new PrintWriter(wr); prw.println("Hello, world"); prw.flush(); InputStream is=sock.getInputStream(); Reader rd=new InputStreamReader(is, "UTF-8"); BufferedReader brd=new BufferedReader(rd); String answer=brd.readLine(); System.out.println(answer); sock.close(); } } 30
  • 31.
    Un server completo import java.io.*; import java.net.*; import javax.net.*; import javax.net.ssl.*; public class SSLEchoServer implements Runnable { public static final int PORT=7777; private Socket sock; public SSLEchoServer(Socket s) { sock=s; } public static ServerSocket createServerSocket(int port) throws IOException { ServerSocketFactory factory=SSLServerSocketFactory.getDefault(); SSLServerSocket sock=(SSLServerSocket) factory.createServerSocket(port); sock.setNeedClientAuth(true); return sock; } // continua ... 31
  • 32.
    Un server completo public static void main(String args[]) throws IOException { System.setProperty("javax.net.ssl.keyStore", "servkeystore.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "pippobaudo"); System.setProperty("javax.net.ssl.trustStore", "servtruststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "pippobaudo"); ServerSocket serv=createServerSocket(PORT); while (true) { Socket sock=serv.accept(); SSLEchoServer server=new SSLEchoServer(sock); Thread t=new Thread(server); t.start(); } } // continua... 32
  • 33.
    Un server completo public void run() { try { BufferedReader brd=new BufferedReader( new InputStreamReader( sock.getInputStream(), "UTF-8")); String s=brd.readLine(); PrintWriter prw=new PrintWriter( new OutputStreamWriter( sock.getOutputStream(), "UTF-8")); prw.print(s); prw.println(s); prw.flush(); } catch (IOException exc) { System.out.println("Eccezione I/O:" + exc); exc.printStackTrace(); } finally { try { sock.close(); } catch (IOException exc2) { } } } } 33