Java Security Extensions(J2SE)



Documenti analoghi
Java Security Extensions Corso di Tecnologie per la Sicurezza LS Prof. R. Laschi. Java Security Extensions

Crittografia in Java

Progetto di Sicurezza

Java Security Extensions

Crittografia & Java Cryptographic. Architecture (JCA) A cura di Franzin Michele Settembre 1 Ottobre Java User Group Padova

Security Model (Java 1.0) Security Model (Java 1.1)

SSL: applicazioni telematiche SSL SSL SSL. E-commerce Trading on-line Internet banking... Secure Socket Layer

Programmazione avanzata Java e C. Crittografia

Indice generale. Prefazione...xiii. Introduzione...xv

Tecnologie per la Sicurezza L-S AA Anna Chiara Bellini o.unibo.it

Introduzione alle esercitazioni

JUG Ancona Italy. Sicurezza in Java. Andrea Del Bene. Membro fondatore Jug Marche

JUG Ancona Italy. Sicurezza in Java. Andrea Del Bene. Membro fondatore Jug Marche

Architettura JCA. Architettura JCA. Provider JCE. Factory pattern. Strategy pattern

JCA e JCE. Crittografia in Java. Java Cryptography Architecture (JCA) Java Cryptography Extension (JCE)

Comunicazioni sicure su Internet: https e SSL. Fisica dell Informazione

RETI DI CALCOLATORI. Crittografia. La crittografia

RC4 RC4. Davide Cerri. Davide Cerri CEFRIEL - Politecnico di Milano cerri@cefriel.it

La firma digitale CHE COSA E'?

Approfondimento di Marco Mulas

Sicurezza nei Sistemi Distribuiti

Sicurezza nei Sistemi Distribuiti

Introduzione alla crittografia con OpenPGP

Corso di Sicurezza Informatica. Sicurezza Web. Ing. Gianluca Caminiti

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto:

12/12/11 Data ultimo aggiornamento

Sicurezza: necessità. Roberto Cecchini Ottobre

! La crittoanalisi è invece la scienza che cerca di aggirare o superare le protezioni crittografiche, accedendo alle informazioni protette

SISTEMI E RETI. Crittografia. Sistemi distribuiti e configurazione architetturale delle applicazioni WEB.

SETEFI. Marco Cantarini, Daniele Maccauro, Domenico Marzolla. 19 Aprile 2012

Gennaio. SUAP On Line i pre-requsiti informatici: La firma digitale

Crittografia e sicurezza informatica. Sistema di voto elettronico

Il glossario della Posta Elettronica Certificata (PEC) Diamo una definizione ai termini tecnici relativi al mondo della PEC.

La gestione dell input/output da tastiera La gestione dell input/output da file La gestione delle eccezioni

PkBox Client Smart API

da chi proviene un messaggio?

Programmare in Java. Olga Scotti

La Sicurezza delle Reti. La Sicurezza delle Reti. Il software delle reti. Sistemi e tecnologie per la multimedialità e telematica.

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

Sicurezza dei sistemi informatici Firma elettronica E-commerce

Pretty Good Privacy. PGP fornisce crittografia ed autenticazione. creato da Phil Zimmermann nel in origine è un'applicazione per

Firma Digitale. dott. Andrea Mazzini

Lezione 7 Sicurezza delle informazioni

Firma digitale Definizione

Applicazioni per l autenticazione Sicurezza nelle reti di TLC - Prof. Marco Listanti - A.A. 2008/2009

FAQ per l utilizzo della piattaforma tecnologica KEP (Key Exchanger Platform)

Java: Compilatore e Interprete

Per scrivere una procedura che non deve restituire nessun valore e deve solo contenere le informazioni per le modalità delle porte e controlli

La Firma Digitale La sperimentazione nel Comune di Cuneo. Pier Angelo Mariani Settore Elaborazione Dati Comune di Cuneo

Android Security Key Management. Roberto Gassirà Roberto Piccirillo

DURC Client 4 - Guida configurazione Firma Digitale. DURC Client 4.1.7

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

Sommario. Introduzione alla Sicurezza Web

PROCEDURA AGGIORNAMENTO LISTE MEDIANTE L INTERFACCIA WEB

Corso di Laurea in Informatica Reti e Sicurezza Informatica

Protezione della posta elettronica mediante crittografia

Esercitazione 2 Certificati

Colloquio SGSS-SIRGESA

Esercitazione 02. Sommario. Un po di background (1) Un certificato digitale in breve. Andrea Nuzzolese

Crittografia con OpenSSL crittografia asimmetrica

Appl. di emissione PKCS#11. API (Metacomandi) Resource Manager Windows. Drivers PC/SC dei lettori

Firma digitale: aspetti tecnologici e normativi. Milano,

Protezione delle informazioni in SMart esolutions

Corso di Informatica (Programmazione) Lezione 6 (31 ottobre 2008)

La sicurezza nelle reti di calcolatori

Corso di Sistemi Operativi Ingegneria Elettronica e Informatica prof. Rocco Aversa. Raccolta prove scritte. Prova scritta

Algebra di Boole: Concetti di base. Fondamenti di Informatica - D. Talia - UNICAL 1. Fondamenti di Informatica

Sicurezza nei Sistemi Informativi

Automatizzare i compiti ripetitivi. I file batch. File batch (1) File batch (2) Visualizzazione (2) Visualizzazione

Meccanismi di autenticazione sicura. Paolo Amendola GARR-CERT

Tale attività non è descritta in questa dispensa

Java Virtual Machine

Funzioni in C. Violetta Lonati

Guida Rapida all uso del License Manager di ROCKEY4Smart (V )

Realizzazione di Politiche di Gestione delle Risorse: i Semafori Privati

Crittografia. Appunti a cura del prof. Ing. Mario Catalano

IPSec VPN Client VPN vs serie ZyWALL con PSK e Certificati digitali

Introduzione ai certificati S/MIME e alla posta elettronica certificata...2 Procedura di installazione del certificato personale S/MIME rilasciato

Sicurezza nelle applicazioni multimediali: lezione 7, sicurezza dei protocolli. Sicurezza dei protocolli (https, pop3s, imaps, esmtp )

Interoperabilità SISTRI Specifiche tecniche per l utilizzo della firma elettronica con il Soft Token PKCS#11

POSTA ELETTRONICA CERTIFICATA

MANUALE UTENTE Fiscali Free

educanet² - Novità Novembre 2007

SICUREZZA. Sistemi Operativi. Sicurezza

Sistemi Operativi SICUREZZA. Sistemi Operativi. D. Talia - UNICAL 14.1

3 - Variabili. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Crittografia con OpenSSL crittografia asimmetrica

La sicurezza nelle reti di calcolatori

DOCUMENTO ELETTRONICO E FIRMA DIGITALE

Fondamenti di Informatica 1. Prof. B.Buttarazzi A.A. 2010/2011

Progettazione : Design Pattern Creazionali

Quasar Sistemi S.r.l.

A intervalli regolari ogni router manda la sua tabella a tutti i vicini, e riceve quelle dei vicini.

FIRMA DIGITALE RETAIL

Software Servizi Web UOGA

SERVIZIO TELEMATICO ENTRATEL. Applicazione Autentica-Apri Multifile

Certificati digitali con CAcert Un'autorità di certificazione no-profit

Portale Remote Sign Manuale Utente

F.A.Q. PROCEDURA SICEANT PER LE COMUNICAZIONI ANTIMAFIA (EX ART 87)

Modulo 4 Il pannello amministrativo dell'hosting e il database per Wordpress

Transcript:

Università degli Studi di Bologna IIª Facoltà di Ingegneria - Cesena Anno Accademico 2010/2011 OUTLINE Java Security Extensions(J2SE) Prof. Enrico Denti Dipartimento di Elettronica, Informatica e Sistemistica enrico.denti@unibo.it Telefono 051.20.93015 2 JAVA SECURITY EXTENSIONS (JSE) PIATTAFORMA JAVA PER LA SICUREZZA Situazione fino al JDK 1.3 Architettura per la sicurezza (JCA) parte del JDK Estensioni per la sicurezza (JSE) fornite a parte (soprattutto per problemi di esportazione dagli USA) Java Web Start fornito a parte Java 2 Security Platform (J2SE 1.4) Java Authentication and Authorization Service (JAAS) Java 2 Security Architecture Novità JDK 1.4 Situazione dal JDK 1.4 (e 1.5) Estensioni JSE fornite insieme al JDK standard Java Web Start fornito insieme al JDK standard Altri miglioramenti: adattamento della gestione dei permessi al modello JAAS gestione dinamica delle politiche di sicurezza miglioramento della sicurezza nella gestione delle applet Java Secure Socket Extension (JSSE) Java Cryptography Extension (JCE) package java.security Java Cryptography Architecture (JCA) Java Generic Security Service (JGSS) Java Certification Path (CertPath) JAVA CRYPTOGRAPHY ARCHITECTURE (JCA) & JAVA CRYPTOGRAPHY EXTENSION (JCE) Il supporto crittografico in Java è articolato su due livelli: la Java Cryptography Architecture (JCA), che definisce la cornice generale per la crittografia: definisce le classi astratte per la gran parte delle funzionalità ma implementa solo alcune funzionalità specifiche in particolare il calcolo di impronte digitali e firme digitali di messaggi la Java Cryptography Extension (JCE), che definisce le API complete e implementa tutte le altre funzionalità in particolare, quelle di cifratura e decifratura di messaggi con algoritmi a piacere JAVA CRYPTOGRAPHY ARCHITECTURE (JCA) Due principi indipendenza dall implementazione e interoperabilità estendibilità e indipendenza degli algoritmi che si traducono in due tipologie di classi: classi astratte "engine" che dichiarano le funzionalità di un certo algoritmo crittografico classi concrete "provider" che implementano un insieme di funzionalità entro un Cryptographic Service Provider (CSP) Molteplicità di provider Più provider possono coesistere ed interoperare il provider di default si chiamasun e fa parte del JRE nuovi provider possono essere installati anche dinamicamente un'applicazione può sia richiedere una implementazione qualsiasi di un algoritmo, sia richiedere quella di un dato provider

PRINCIPALI CLASSI "ENGINE" Packagejava.security Key definisce le funzionalità condivise da chiavi opache KeySpec definisce una chiave di tipo trasparente KeyFactory rende una chiave opaca o trasparente KeyPairGenerator genera una coppia di chiavi asimmetriche AlgorithmParameters gestisce i parametri di un algoritmo AlgorithmParameterGenerator genera i parametri di un algoritmo MessageDigest calcola l hash (message digest) di un messaggio SecureRandom genera numeri casuali o pseudo-casuali Signature appone o verifica la firma digitale di un messaggio CertificateFactory crea e revoca certificati di chiavi pubbliche KeyStore gestisce il database (keystore) di chiavi e certificati NB: opaco e trasparente non sono sinonimi di cifrato e in chiaro. opaco = non si può accedere a ciò che costituisce la chiave direttamente, ma solo tramite i metodi dell'interfaccia Key; trasparente = non opaco. CHIAVI: INTERFACCE E CLASSI KeyFactory (JCA) + SecretKeyFactory (JCE) Key INTERFACCE DERIVATE DHPrivateKey DHPublicKey DSAPrivateKey DSAPublicKey SecretKey PBEKey PrivateKey PublicKey RSAMultiPrimePrivateCrtKey RSAPrivateCrtKey RSAPrivateKey RSAPublicKey PublicKey generatepublic (KeySpec keyspec) PrivateKey generateprivate(keyspec keyspec) SecreteKey generatesecret (KeySpec keyspec) KeySpec CLASSI IMPLEMENTATIVE DHPrivateKeySpec DHPublicKeySpec DSAPrivateKeySpec DSAPublicKeySpec SecretKeySpec PBEKeySpec RSAPrivateKeySpec RSAPublicKeySpec EncodedKeySpec DESedeKeySpec DESKeySpec KeySpec getkeyspec(key key, Class keyspec) COSA IMPLEMENTA: gli algoritmi di message digest MD5 e SHA-1 l algoritmo di firma digitale DSA (Digital Signature Algorithm) e i relativi enti di supporto specifici per DSA: KeyFactory e KeyPairGenerator AlgorithmParameters e AlgorithmParameterGenerator e inoltre: IL PROVIDERsun l algoritmo di generazione casuale SHA1PRNG (algoritmo proprietario, raccomandazione standard IEEE P1363) unacertificatefactory per certificati X.509 e per Certificate Revocation List una implementazione del KeyStore proprietario JKS Oltre al provider sun ne vengono forniti (JDK 1.4) altri due che estendono l'insieme delle funzionalità disponibili: rsajca SunJCE ALTRI PROVIDER PREDEFINITI in particolare verso l algoritmo di firma digitale RSA solo per firma e verifica svariati algoritmi di cifratura tra cui: DES, TripleDES, Blowfish (e relativi generatori di chiavi) Diffie-Hellman per negoziazione di chiavi INSTALLAZIONE DI NUOVI PROVIDER Se le funzionalità offerte dal provider Sun non bastano, si possono installare altri provider, sia staticamente sia dinamicamente. 1. INSTALLAZIONE STATICA porre l archivio JAR del nuovo provider nella cartella relativa alle estensioni del JRE, $JAVA_HOME/jre/lib/ext aggiungere al file delle specifiche di sicurezza java.security (contenuto in $JAVA_HOME\jre\lib\security) la riga security.provider.n =ProviderName dove N rappresenta la priorità di quel provider; la macchina virtuale Java sceglie i provider seguendo tale ordine. 2. INSTALLAZIONE DINAMICA non ci sono passi preliminari da compiere. INSTALLAZIONE STATICA: ESEMPIO I provider predefiniti sono elencati nelle prime 5 righe del file $JAVA_HOME/jre/lib/security/java.security security.provider.1=sun.security.provider.sun security.provider.2=com.sun.net.ssl.internal.ssl.provider security.provider.3=com.sun.rsajca.provider security.provider.4=com.sun.crypto.provider.sunjce security.provider.5=sun.security.jgss.sunprovider security.provider.6=org.bouncycastle.jce.provider.bouncycastleprovider In questo esempio, la sesta riga installa staticamente il provider BouncyCastle (www.bouncycastle.com), il cui file JAR dev'essere posto nella directory $JAVA_HOME/jre/lib/ext

INSTALLAZIONE DINAMICA: ESEMPIO L'installazione dinamica si svolge da programma Java, utilizzando le apposite API della classesecurity: static int addprovider(provider provider) static Provider getprovider(string name) static Provider[] getproviders() static Set getalgorithms(string servicename) static int insertproviderat(provider provider, int position) Ad esempio, per installare il provider IAIK (scaricabile da http://jce.iaik.tugraz.at/products/01_jce/index.php): import javax.crypto.*; import iaik.security.provider.*; IAIK provider = new IAIK(); Security.addProvider(provider); LE JAVA SECURITY EXTENSIONS Le estensioni JCE e JSSE implementano due provider che estendono le funzionalità del provider di base: SunJCE SunJSSE crittografia a livello locale crittografia a livello di rete Altri package forniscono funzionalità di sicurezza aggiuntive, complementari alla JCA: JAAS servizi di autenticazione, autorizzazione e amministrazione CertPath gestione di catene di certificati (certification paths) JGSS meccanismi di comunicazione generici e specifici (Kerberos v5) JCA & JSE: SCHEMA D'USO Tutte le classi engine della JCA e della JSE si usano secondo il pattern "Factory", ossia: non si istanziano oggetti direttamente, tramite new si usa invece un metodo statico "di fabbrica", che nasconde e incapsula la fase di creazione esplicita: getistance(string nomeistanza) Questo metodo può così restituire formalmente delle interfacce, separando completamente l'uso (espresso dalle interfacce) dagli aspetti implementativi (legati alle classi utilizzate internamente). ESEMPI: KeyGenerator kg = KeyGenerator.getInstance("TripleDES"); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); Signature sig = Signature.getInstance("MD5WithRSA"); CertificateFactory cf = CertificateFactory.getInstance("X.509"); JCE: CARATTERISTICHE La Java Cryptography Extension (JCE) fornisce una implementazione completa delle funzionalità di cifratura e decifratura dichiarate dalla JCA Supporta cifrari simmetrici (a blocchi e a flusso), cifrari asimmetrici e cifrari con password, unitamente ai meccanismi di MAC (Message Authentication Code) e generazione / negoziazione di chiavi; tutti gli algoritmi sono applicabili su dati, stream di I/O e oggetti serializzabili. Il package principalejavax.crypto include fra le altre: Cipher (cifratura e decifratura di dati con uno specifico algoritmo) CipherInputStream /CipherOutputStream (canale sicuro, ossia un Cipher + un InputStream o un OutputStream) KeyGenerator (generazione di chiavi per algoritmi simmetrici e per lo scambio Diffie-Hellmann DH) Mac (Message Authentication Code MAC) MODALITÀ e PADDING (RIEMPIMENTI) La MODALITÀ definisce come il cifrario debba applicare l'algoritmo di cifratura: può essere a blocchi o a flusso. Casi tipici sono: ECB [Elettronic Code Book]: uno stesso blocco di testo, anche se ripetuto, dà sempre luogo allo stesso blocco di testo cifrato CBC [Cipher Block Chaining]: ogni blocco cifrato dipende sia dal relativo blocco in chiaro, sia da tutti i blocchi precedenti, sia da un opportuno vettore di inizializzazione. Il PADDING stabilisce come completare un blocco che non raggiunge la dimensione fissa prestabilita. PKCS#5 [Public Key Criptography Standard n 5] è lo schema di riempimento più usato per la cifratura simmetrica: ai byte che mancano per riempire un blocco si assegna un valore pari al numero di byte mancanti. h e l l o 3 3 3 t e s t 4 4 4 4 8 8 8 8 8 8 8 8 c i p h e r 2 2 ESEMPIO CON 3DES: inizializzazione import java.security.*; import javax.crypto.*; Istanzia un generatore di public class TripleDES { chiavi di tipo TripleDES public static void main (String[] args) { Con il provider BouncyCastle si String text = "Hello world!"; userebbe la stringa "DESede" if (args.length == 1) text = args[0]; KeyGenerator keygen = KeyGenerator.getInstance("TripleDES"); keygen.init(168); Key key = keygen.generatekey(); Cipher cipher = Cipher.getInstance("TripleDES/ECB/PKCS5Padding"); Inizializza il generatore con la lunghezza in bit della chiave Per TripleDES, è sempre 168 Generazione della chiave Crea il cifrario, indicando: Tipo di chiave [TripleDES] Modalità [ECB] Padding [PKCS5Padding]

ESEMPIO CON 3DES: cifratura. cipher.init(cipher.encrypt_mode, key); byte[] plaintext = text.getbytes("utf8"); System.out.println("\nPlain text: "); for (int i=0;i<plaintext.length;i++) System.out.print(plaintext[i]+" "); Inizializza il cifrario per cifrare Converte una stringa in un array di byte specificando la codifica. ESEMPIO CON 3DES: decifratura cipher.init(cipher.decrypt_mode, key); byte[] decryptedtext = cipher.dofinal(ciphertext); String output = new String(decryptedText,"UTF8"); System.out.println("\nDecrypted Text: "+output);. Inizializza il cifrario per decifrare (usiamo la stessa chiave) Decifra i dati byte[] ciphertext = cipher.dofinal(plaintext); System.out.println("\nCipher text: "); for(int i=0;i<ciphertext.length;i++) System.out.print(ciphertext[i]+" ");. Cifra i dati COMPILAZIONE ED ESECUZIONE: C:> javac TripleDES.java C:> java TripleDES testoinchiaro Supponiamo: "Hello world!" NB: prima di cifrare chiamandodofinal, si possono eventualmente aggiungere altri dati invocando il metodoupdate(byte[]); anche in tal caso occorre ricordarsi di specificare la codifica. Plain text: 72 101 108 108 111 32 119 111 114 108 100 33 Cipher text: 23 28-14 60-14 45-6 23 12 53 71 58 123 90-108 -57 Decrypted Text: Hello world! ESEMPIO CON 3DES: COMPLETAMENTO Per funzionare, il codice precedente dev'essere completato con la gestione delle eccezioni: catch (NoSuchAlgorithmException e1) { System.out.println("Algoritmo non supportato"); catch (InvalidAlgorithmParameterException e2) { System.out.println("Parametro non valido"); catch (NoSuchProviderException e2) { System.out.println("Algoritmo non supportato dal provider"); catch (NoSuchPaddingException e3) { System.out.println("Padding non supportato"); catch (BadPaddingException e4) { System.out.println("Padding non riuscito"); catch (InvalidKeyException e5) { System.out.println("Chiave non valida"); catch (IllegalBlockSizeException e6) { System.out.println("Dimensione blocco non corretta"); catch (UnsupportedEncodingException e7) { System.out.println("Codifica non supportata"); CAMBIARE ALGORITMO: ESEMPI Cambiare algoritmo significa solo creare un diverso cifrario. Ad esempio, volendo utilizzare Blowfish anziché 3DES: KeyGenerator keygen = KeyGenerator.getInstance("Blowfish"); keygen.init(128); Cipher c = Cipher.getInstance("Blowfish/ECB/PKCS5Padding"); Analogamente per l'algoritmo Rijndael, che opera in modalità CBC: Cipher c = Cipher.getInstance("Rijndael/CBC/PKCS5Padding"); byte[] initvect = new byte[16]; 16 byte casuali necessari SecureRandom random = new SecureRandom(); per la generazione del random.nextbytes(initvect); seme IvParameterSpec spec = new IvParameterSpec(initVect); cipher.init(cipher.encrypt_mode, key, spec); Inizializza il cifrario passando anche il semespec CIFRATURA CON PASSWORD (PBE) Password-Based Encryption (PBE): caratteristiche password di un utente medio = circa 6 caratteri 48 bit contro le chiavi di 448 bit di 3DES e Blowfish password tipiche = parole con un qualche significato spazio delle chiavi ancora più limitato soggette ad attacchi con dizionario Due difese contemporanee: ing = aggiunta di un insieme di bit casuali alla password in modo ampliare lo spazio delle chiavi Conteggi di ripetizione = chiave del cifrario PBE separata rispetto alla password: la chiave PBE è ottenuta ripetendo molte volte un'operazione sulla password base. in chiaro Password CIFRARIO CON PASSWORD + SALT CIFRARIO PBE DATI CIFRATI cifrato DATI CIFRATI cifrato cifrato cifrato Password CIFRARIO PBE in chiaro

CIFRATURA CON PBE: ESEMPIO import java.security.*; import javax.crypto.*; import java.util.*; public class ProvaPBE { private final int ITERATIONS = 1000; import java.security.spec.*; import javax.crypto.spec.*; public static String encrypt(char[] password, String plaintext) { Random random = new Random(); byte[] salt = new byte[8]; random.nextbytes(salt); PBEKeySpec keyspec = new PBEKeySpec(password); Crea la chiave PBE SecretKeyFactory keyfactory = data la password SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey key = keyfactory.generatesecret(keyspec); PBEParameterSpec paramspec = new PBEParameterSpec(salt, ITERATIONS); Incapsula salt e numero di iterazioni Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES"); cipher.init(cipher.encrypt_mode, key, paramspec); byte[] ciphertext = cipher.dofinal(plaintext.getbytes("utf8")); return new String(salt) + new String(ciphertext); DECIFRATURA CON PBE: ESEMPIO public static String decrypt(char[] password, String input) { byte[] salt = input.substring(0,8).getbytes("utf8"); byte[] ciphertext = input.substring( 8 ).getbytes("utf8"); Separa il salt dal testo cifrato e li converte in array di byte PBEKeySpec keyspec = new PBEKeySpec(password); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey key = keyfactory.generatesecret(keyspec); PBEParameterSpec paramspec = Tutto come prima new PBEParameterSpec(salt, ITERATIONS); Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES"); cipher.init(cipher.decrypt_mode, key, paramspec); byte[] plaintextarray = cipher.dofinal(ciphertext); return new String(plaintextArray ); a parte ovviamente il DECRYPT MODE e lo scambio di ruoli fra testo in chiaro e testo cifrato MEMORIZZAZIONE SICURA DELLA CHIAVE PROBLEMA: DOVE memorizzare la chiave? su floppy disc o smart card? scomodo (servono mezzi fisici esterni) su disco fisso? comodo.. ma la sicurezza..? è opportuno cifrare la chiave, ad esempio con PBE non è male poi proteggere ulteriormente la chiave, ad esempio impostando i permessi di accesso al file Cifratura: byte[] keybytes = key.getencoded(); cipher.init(cipher.encrypt_mode, password, paramspec); byte[] encryptedkeybytes = cipher.dofinal(keybytes); Decifratura: cipher.init(cipher.decrypt_mode, password, paramspec); byte[] keybytes = cipher.dofinal(encryptedkeybytes); SecretKeySpec key = new SecretKeySpec(keyBytes, "Blowfish"); Alcuni provider forniscono un mezzo più comodo per cifrare la chiave, evitando la conversione da byte[] akey Si incapsula una chiave segreta configurando un cifrario PBE in WRAP_MODE (anzichéencrypt_mode) e poi usandowrap anzichédofinal. Analogamente si recupera la chiave operando sul cifrario in UNWRAP_MODE (anzichédecrypt_mode) e poi usandounwrap anzichédofinal. Cifratura: INCAPSULAMENTO ED ESTRAZIONE DELLA CHIAVE cipher.init(cipher.wrap_mode, password, paramspec); byte[] encryptedkeybytes = cipher.wrap(key); Decifratura: cipher.init(cipher.unwrap_mode, password, paramspec); Key key = cipher.unwrap(encryptedkeybytes, "Blowfish", Cipher.SECRET_KEY); CipherInputStream ecipheroutputstream realizzano il concetto di canale sicuro combinando automaticamente uninputstream o unoutputstream con uncipher incaricato di gestire cifratura e decifratura. Creazione stream cifrati: STREAM CIFRATI CipherOuputStream cipheroutput = new CipherOutputStream(new FileOutputStream(cipherFileName), cipher); CipherInputStream cipherinput = new CipherInputStream( new FileInputStream( cipherfilename), cipher); Uso (trasparente) di stream cifrati: int ch = 0; Un Inputstream qualsiasi Ogni carattere scritto viene automaticamente cifrato while ((ch = input.read())!=-1) { cipheroutput.write(ch); cipheroutput.close(); OGGETTI SIGILLATI Gli oggetti sigillati (SealedObject) sono oggetti cifrati che incapsulano il cifrario Sono utili per memorizzare e trasportare una versione cifrata di un oggetto (serializzabile) import java.io.*; import javax.crypto.*; import java.security.*; public class SealedObjectExample { public static void main (String[ ] args) { String secretmessage = "Ci vediamo domani alle 15"; KeyGenerator keygenerator = KeyGenerator.getInstance("Blowfish"); Key key = keygenerator.generatekey(); Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding"); cipher.init(cipher.encrypt_mode, key); SealedObject so = new SealedObject(secretMessage, cipher); String decryptedmessage = (String) so.getobject(key); System.out.println("Messaggio decifrato: " + decryptedmessage);

CIFRATURA ASIMMETRICA FIRMA DIGITALE: GENERAZIONE e INVIO Algoritmo di impronta CIFRATURA ASIMMETRICA FIRMA DIGITALE: RICEZIONE e VERIFICA Algoritmo di impronta Messaggio da firmare Impronta del messaggio Messaggio ricevuto Impronta del messaggio Chiave privata del mittente Chiave pubblica del mittente UGUALI? Impronta del messaggio Lato Mittente Algoritmo di firma Firma digitale da inviare al destinatario insieme al messaggio Firma digitale ricevuta dal mittente Algoritmo di verifica della firma Lato Destinatario RSA vs DSA: CONFRONTO Firmare con RSA significa cifrare con la chiave privata decifrare con la pubblica Questa operazione non nasconde i dati (che sono decifrabili con la chiave pubblica) ma prova l identità del firmatario L'algoritmo DSA (Digital Signature Algorithm) è analogo a RSA per la firma, ma non può essere usato per cifrare DSA è più veloce a generare le firme, RSA a verificarle poiché una firma viene convalidata più spesso di quanto venga generata, RSA è solitamente più veloce APPOSIZIONE DI UNA FIRMA DIGITALE import java.security.signature; import java.security.signatureexception; KeyPairGenerator keypairgen = KeyPairGenerator.getInstance("RSA"); keypairgen.initialize(1024); KeyPair keypair = keypairgen.genkeypair(); byte[] msg = "Non esistono più le mezze stagioni".getbytes("utf8"); Signature sig = Signature.getInstance("MD5WithRSA"); sig.initsign(keypair.getprivate()); sig.update(msg); byte[] signaturebytes = sig.sign(); Per firmare occorre un oggetto Signature PROCEDURA DI FIRMA: si inizializza l'oggetto Signature con la chiave PRIVATA del mittente gli si passano mediante update i dati da firmare si calcola la firma invocando sign che restituisce i byte costituenti la firma E CORRISPONDENTE VERIFICA import java.security.signature; import java.security.signatureexception; sig.initverify( keypair.getpublic() ); sig.update(msg); boolean verified = false; try { verified = sig.verify(signaturebytes); catch (SignatureException se) { System.out.println("Formato non valido"); Anche per verificare la fiorma occorre un oggetto Signature PROCEDURA DI VERIFICA: si inizializza l'oggetto Signature con la chiave PUBBLICA del mittente gli si passano mediante update i dati da VERIFICARE si verifica la firma invocandoverify che restituisce un boolean CIFRATURA ASIMMETRICA vs. CIFRATURA SIMMETRICA DIFFERENZE RISPETTO AL CASO SIMMETRICO MODALITÀ: nei cifrari asimmetrici, si usa quasi sempre ECB PADDING: nei cifrari asimmetrici non si usa più PKCS#5, ma bensì (con RSA) PKCS#1 e OAEP (Optimal Asymmetric Encryption Padding) COSA SI CIFRA: tipicamente solo la (corta) chiave di sessione da usarsi da lì in poi con un algoritmo simmetrico. COSA OCCORRE solo per firmare digitalmente un messaggio e verificarlo: basta il provider JCE standard per cifratura e decifratura: un provider che supporti tutto RSA BouncyCastle o IAIK

CIFRATURA ASIMMETRICA con RSA import javax.crypto.*; import java.security.*; KeyPairGenerator keypairgen = KeyPairGenerator.getInstance("RSA"); keypairgen.initialize(1024); KeyPair keypair = keypairgen.genkeypair(); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(cipher.encrypt_mode, keypair.getpublic() ); Tipicamente il messaggio da cifrare sarà la chiave di sessione byte[] messagebytes = "il mio messaggio".getbytes("utf8"); byte[] ciphertext = cipher.dofinal(messagebytes); cipher.init(cipher.decrypt_mode, keypair.getprivate() ); byte[] decryptedmessagebytes = cipher.dofinal(ciphertext); System.out.println( new String(decryptedMessageBytes,"UTF8") ); CIFRATURA ASIMMETRICA con RSA DI UNA CHIAVE (simmetrica) DI SESSIONE KeyPairGenerator keypairgen = KeyPairGenerator.getInstance("RSA"); keypairgen.initialize(1024); KeyPair keypair = keypairgen.genkeypair(); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(cipher.encrypt_mode, keypair.getpublic() ); KeyGenerator sessionkeygen = KeyGenerator.getInstance("Blowfish"); sessionkeygen.init(128); Key blowfishkey = sessionkeygen.generatekey(); byte[] blowfishkeybytes = blowfishkey.getencoded(); byte[] ciphertext = cipher.dofinal(blowfishkeybytes); cipher.init(cipher.decrypt_mode, keypair.getprivate() ); byte[] decryptedkeybytes = cipher.dofinal(ciphertext); SecretKey reconstructedblowfishkey = new SecretKeySpec(decryptedKeyBytes,"Blowfish");