Programmazione avanzata Java e C. Crittografia

Documenti analoghi
Crittografia in Java

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

Java Security Extensions(J2SE)

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

Piattaforma AlmaChannel e laboratori virtuali

Crittografia a chiave pubblica

Converte una chiave di al più 14 word a 32 bit (K-array) in un array di 18 sottochiavi a 32 bit (P-array) Genera 4 S-box, ognuna con 256 word a 32 bit

Esercitazione 03. Sommario. Gnu Privacy Guard (GPG) Chiavi GPG (1/2) Andrea Nuzzolese. Gnu Privacy Guard (GPG) Descrizione esercitazione

Sicurezza nelle reti: protezione della comunicazione

RSA in OpenSSL. Alfredo De Santis. Marzo Dipartimento di Informatica Università di Salerno.

Sicurezza dei Sistemi Informatici Esercitazioni OpenSSL

Steganografia in un. Corso di Sicurezza dei sistemi informatici Michelangelo Rinelli Anno Accademico 2005/06

Elementi di crittografia

Crittografia per la sicurezza dei dati

CRITTOGRAFIA 2014/15 Appello del 13 gennaio Nome: Cognome: Matricola:

Cifratura simmetrica

idea della crittografia a chiave pubblica

Laboratorio di Crittografia I - PGP/GPG

Il Blowfish per la crittografia dei dati

Cifrari a blocchi. Esercizi con OpenSSL. Alfredo De Santis. Marzo Dipartimento di Informatica Università di Salerno

Cifratura Simmetrica con OpenSSL

Corso di Crittografia Prof. Dario Catalano. Firme Digitali

Crittografia e OpenSource

Laboratorio di Programmazione Lezione 2. Cristian Del Fabbro

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

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

Crittografia a chiave pubblica

Data Encryption Standard. Data Encryption Standard DES. Struttura del DES. Lunghezza della Chiave. Permutazione Iniziale IP

Lezione 6 programmazione in Java

Crittografia con OpenSSL crittografia simmetrica

RETI DI CALCOLATORI Linguaggio Java: Eccezioni

Le classi in java. Un semplice programma java, formato da una sola classe, assume la seguente struttura:

Firma digitale e PEC: aspetti crittografici e sicurezza

Corso sul linguaggio Java

logaritmo discreto come funzione unidirezionale

Transcript:

Programmazione avanzata Java e C Crittografia

ü JCA o Java Cryptography Architecture è il framework java per la crittografia che fa parte della API di sicurezza di Java, ed è stato introdotto nei pacchetti java.security e java.crypto. JCA fornisce le principali funzionalità di crittografia quali: ü firma digitale; ü message digest (hash); ü certificati e convalida dei certificati; ü crittografia (simmetrica/blocco asimmetrico/cifrari a flusso); ü generazione e gestione di chiavi; ü generazione di numeri casuali e molto altro.

ü La chiave crittografica è una informazione che è utilizzata in un algoritmo di criptazione e decriptazione per generare un testo cifrato da uno in chiaro. ü Possono avere lunghezza variabile in funzione dell algoritmo utilizzato ed in generale si parla di chiavi simmetriche o asimmetriche. JCA offre le funzionalità per la generazione di entrambe le tipologie di chiavi. ü La classe KeyGenerator espone le funzionalità per la generazione di chiavi simmetriche. Per istanziarla possiamo invocare il metodo getinstance() specificando l algoritmo che si intende utilizzare.

Si noti che questa modalità di istanziare gli di oggetti in JCA è molto comune perché il framework è progettato in modo da demandare l implementazione degli algoritmi a provider esterni registrati. La stringa di input specifica l implementazione (ovvero algoritmo) richiesta e se non presente il metodo restituisce l eccezione NoSuchAlgorithmException.

Il codice seguente generare una chiave simmetrica. private static final String SYM_ALGORITHM = "AES"; private static final Integer SYM_KEY_SIZE = 128; public static Key generatesymmetrickey() throws NoSuchAlgorithmException { KeyGenerator generator = KeyGenerator.getInstance( SYM_ALGORITHM ); generator.init( SYM_KEY_SIZE ); SecretKey key = generator.generatekey(); return key; }

Gli algoritmi disponibili nel JCA, con le rispettive lunghezze in bit delle chiavi, sono i seguenti: ü AES (128) ü 1/7DES (56) ü DESede (168) ü HmacSHA1 ü HmacSHA256

Per la generazione di una coppia di chiavi asimmetriche (pubblica e privata) la classe del framework da utilizzare è KeyPairGenerator. La coppia di chiavi è restituita nel bean KeyPair caratterizzata da due sole proprietà in sola lettura: publickey e privatekey.

private static final String ASYM_ALGORITHM = "RSA"; private static final Integer ASYM_KEY_SIZE = 1024; public static KeyPair generateasymmetrickey() throws NoSuchAlgorithmException { KeyPairGenerator generator = KeyPairGenerator.getInstance( ASYM_ALGORITHM ); generator.initialize( ASYM_KEY_SIZE ); return generator.generatekeypair(); }.

Gli algoritmi supportati dal framework sono: ü DiffieHellman (1024) ü DSA (1024) ü RSA (1024, 2048)

La crittografia simmetrica o crittografia a chiave privata indica un metodo di cifratura molto semplice in cui la chiave utilizzata per cifrare il testo in chiaro è la stessa utilizzata per decifrarlo. La figura seguente mostra il processo appena descritto.

La classe che espone i servizi per la crittazione e decrittazione è java.crypto.cipher. Come già visto per ottenerne una istanza è necessario invocare il metodo getinstance() passando una stringa (transformation) cheindica il set di operazioni che devono essere eseguite sull input per ottenere l output richiesto. Tale stringa ha il formato algorithm/mode/padding dove: ü algorithm indica l algoritmo di crittazione desiderato; ü mode indica il metodo di crittazione che può essere a Blocchi di Cifre o a Flusso di Cifre; ü padding nel caso di cifratura a blocchi indica l algoritmo da utilizzare per riempire il blocco finale.

Il codice seguente mostra un esempio di cifratura simmetrica con algoritmo di cifratura a blocchi AES in modalità CBC. Il metodo CBC combina il blocco corrente con l esito della crittazione del blocco precedente, quindi necessita di un vettore di inizializzazione per cifrare il primo blocco.

public static byte [] encrypt( Key key, byte[] iv, byte[] plaintext ) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { Cipher cipher = Cipher.getInstance( "AES/CBC/PKCS5Padding" ); cipher.init( Cipher.ENCRYPT_MODE, key, new IvParameterSpec( iv ) ); return cipher.dofinal( plaintext ); }

L oggetto Cipher può essere utilizzato sia per criptare che per decriptare. La selezione della modalità operativa si effettua passando il parametro mode al metodo init(), che nel nostro esempio assume il valore ENCRYPT_MODE. A tale metodo passiamo anche la chiave da utilizzare per l operazione ed il vettore di inizializzazione.

Per eseguire l operazione inversa di decriptazione il codice java sarà simile al precedente ma l operazione specificata nel metodo init() dovrà essere DECRYPT_MODE.

public static byte [] decrypt( Key key, byte[] iv, byte[] ciphertext ) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { Cipher cipher = Cipher.getInstance( "AES/CBC/PKCS5Padding" ); cipher.init( Cipher.DECRYPT_MODE, key, new IvParameterSpec( iv ) ); return cipher.dofinal( ciphertext ); }

Si utilizza la classe SecureRandom che utilizza algoritmi per la generazione di numeri casuali non facilmente predicibile. public static byte [] generateinitvector() { SecureRandom random = new SecureRandom(); byte [] iv = new byte [ SYM_KEY_SIZE / 8 ]; random.nextbytes( iv ); return iv; }

La crittografia asimmetrica, conosciuta anche come crittografia a chiave pubblica/privata o solamente crittografia a chiave pubblica, è un metodo di criptazione in cui si utilizza una coppia di chiavi diverse, una pubblica ed una privata, in grado di funzionare solo l una con l altra. La chiave privata è utilizzabile solo dal legittimo possessore, mentre quella pubblica è resa nota a chiunque.

In pratica, ciò che viene cifrato da una chiave può essere decifrato solo con l altra chiave della coppia e viceversa. Sebbene più sicura, in quanto elimina il problema della condivisione della chiave tra mittente e destinatario, risulta computazionalmente più onerosa rispetto ad un algoritmo a chiave simmetrica.

Per questo motivo è generalmente utilizzato per cifrare solamente pochi blocchi di dati, come ad esempio la una chiave simmetrica. E poi la chiave simmetrica(detta anche chiave di sessione) che viene utilizzata per la criptazione del testo, come mostrato nell immagine seguente.

public static byte [] encrypt( PublicKey key, byte[] plaintext ) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { Cipher cipher = Cipher.getInstance( "RSA/ECB/NoPadding" ); cipher.init( Cipher.ENCRYPT_MODE, key ); return cipher.dofinal( plaintext ); }

public static byte [] decrypt( PrivateKey key, byte[] ciphertext ) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { Cipher cipher = Cipher.getInstance( key.getalgorithm() + "/ECB/NoPadding" ); cipher.init( Cipher.DECRYPT_MODE, key ); return cipher.dofinal( ciphertext ); }

Tutti i metodi di cifratura e decifratura che abbiamo visto ricevono in input e restituiscono in output un array di byte. Per poter persistere o trasferire tale array attraverso un media che tratta dati testuali è necessario convertirlo in Base 64. Questo per garantire che il dato rimanga intatto durante il trasporto.

private static final BASE64Encoder encoder = new BASE64Encoder(); private static final BASE64Decoder decoder = new BASE64Decoder(); public static String base64encode( byte[] array ) { return encoder.encode( array ); } public static byte[] base64decode( String buffer ) throws Exception { return decoder.decodebuffer( buffer ); }

In conclusione inserendo i metodi descritti sopra in una classe CryptoHelper le operazioni di criptazione e decriptazione avvengono nel modo seguente:

public static void main(string[] args) throws Exception { String msg = "Questo è il testo da proteggere"; // Cifratura con chiave simmetrica Key key = CryptoHelper.generateSymmetricKey(); byte[] iv = CryptoHelper.generateInitVector(); String encripted = CryptoHelper.base64Encode( CryptoHelper.encrypt( key, iv, msg.getbytes() ) ); System.out.println( encripted ); // ----------------------- // Invio messaggio cifrato // ----------------------- // Decifratura con chiave simmetrica String decripted = new String( CryptoHelper.decrypt( key, iv, CryptoHelper.base64Decode( encripted ) ) );

System.out.println( decripted ); // Cifratura con chiave simmetrica KeyPair keypair = CryptoHelper.generateAsymmetricKey(); encripted = CryptoHelper.base64Encode( CryptoHelper.encrypt( keypair.getpublic(), iv, msg.getbytes() ) ); System.out.println( encripted ); // ----------------------- // Invio messaggio cifrato // ----------------------- // Decifratura con chiave asimmetrica decripted = new String( CryptoHelper.decrypt( keypair.getprivate(), iv, CryptoHelper.base64Decode( encripted ) ) ); System.out.println( decripted ); }