Crittografia Simmetrica in Java
La crittografia simmetrica in java è un algoritmo che usa la stessa chiave K per la cifratura e decifratura. Implementazioni di DES, DESede (TripleDes), AES
La crittografia simmetrica in java è un algoritmo a chiave simmetrica che usa la stessa chiave K sia per la cifratura, sia per la successiva decifratura.
Le implementazioni svolte nella Demo fanno riferimento ai seguenti algoritmi di Cifratura:
- DES
- DESede (TripleDes)
- AES
Il primo usa una chiave a 64 bit, il secondo una chiave a 192 bit ed il terzo una chiave a 128 bit.
Vengono usate due modalità di cifratura:
- ECB: dove ogni blocco da cifrare viene cifrato direttamente con la chiave simmetrica K.
- CBC: dove il primo blocco viene XORato con un IV generato Random e crittografato con la chiave K, e la risultate codifica generata viene XORata con il blocco successivo del testo in chiaro e codificato con la chiave K, e così via fino all’ultimo blocco del testo in chiaro.
E vengono usati i seguenti Padding:
- NoPadding: non viene inserita nessuna sequenza di byte nell’ultimo blocco del testo in chiaro, quindi si suppone che il testo in chiaro sia un multiplo del blocco di cifratura.
- PKCS5Padding: viene aggiunta all’ultimo blocco del testo in chiaro una sequenza di byte in modo da renderlo della stessa grandezza del blocco per la cifratura.
Implementazione
Le principali classi ed interfacce utilizzate sono state:
- crypto.Cipher
- getInstance, init , update, doFinal
- security.Key (interfaccia)
- Un oggetto Key viene creato con un factory:
- crypto.KeyGenerator (se generiamo la chiave senza specifiche iniziali)
- security.KeyFactory (se vogliamo che la chiave sia generata seguendo delle specifiche iniziali)
- crypto.KeyGenerator
- getInstance, init, generateKey
- Un oggetto Key viene creato con un factory:
Vediamo nello specifico la classe principale utilizzata per eseguire Cifratura Simmetrica (la classe Cipher)
La classe Cipher è un engine class, una classe astratta che definisce le funzionalità di un dato tipo di algoritmo crittografico, senza però fornire alcuna implementazione, questa sarà definita con il metodo getInstance dove noi andremo a inserire il Provider e le informazioni sull’algoritmo che utilizzeremo.
- getInstance (“Algoritmo/Modalità/Padding”, “Provider”);
- Algoritmo:
- DES
- DESede
- AES
- Modalità
- ECB
- CBC
- Padding
- NoPadding
- PKCS5Padding
- Provider
- SUN
- Può essere anche omesso usa quello standard SunJCE
- Algoritmo:
Altri metodi della classe Cipher utilizzati sono:
- init(mode, key)
- mode:
- ENCRYPT_MODE (modalità di cifratura)
- DECRYPT_MODE (modalità di decifratura)
- update(bytes) (vengono inseriti i bytes da elaborare)
- doFinal(bytes) (esegue la Codifica o Decodifica sui bytes passati in input)
- mode:
I passi della Crittografia Simmetrica
I passi per effettuare la Crittografia Simmetrica in ambiente Java sono i seguenti
(ora un esempio di Crittografia Des in modalità ECB):
- Creazione di una chiave
- KeyGenerator keyGenerator = KeyGenerator.getIstance(“DES”);
- init(64);
- SecretKey key = keyGenerator.generateKey();
- Creazione ed inizializzazione di un cifrario
- Chiper cipher = Cipher.getInstance(“DES/ECB/PKCS5Padding”);
- Cifratura
- init(Cipher.ENCRYPT_MODE, key);
- byte[] cipherText = cipher.doFinal(stringToEncrypt.getBytes());
- Decifratura
- init(Cipher.DECRYPT_MODE, key);
- byte[] plainText = cipher.doFinal(cipherText);
La classe KeyGenerator si occupa di generare una chiave simmetrica DES di lunghezza 64 bit. Con getInstance(“DES”) si definisce l’algoritmo per cui sarà usata la chiave, con init(64) si definisce la lunghezza della chiave e con generateKey() viene creata la chiave.
Adesso guardiamo la differenza con la modalità CBC (un esempio di Cifratura Des in modalità CBC):
- Creazione di una chiave
- KeyGenerator keyGenerator = KeyGenerator.getInstance(“DES”);
- SecretKey key = keyGenerator.generateKey();
- Creazione ed inizializzazione di un cifrario
- byte[] randomBytes = new byte[8]; //iv size = block size
- SecureRandom random = new SecureRandom();
- nextBytes(randomBytes);
- IvParameterSpec ivparams = new IvParameterSpec(randomBytes);
- Cipher cipher = Cipher.getInstance(“DES/CBC/PKCS5Padding”);
- init(Cipher.ENCRYPT_MODE, key, ivparams); // cifratura
- init(Cipher.DECRYPT_MODE, key, ivparams); // decifratura
La differenza sta nell’utilizzo di una variabile IV generata Random.
C’è anche un modo alternativo per la generazione della chiave, invece di lasciarla generare al KeyGenerator( ) la si fa generare a partire da una stringa.
- String password = “password”;
- byte[] desKeyData = password.getBytes();
- DESKeySpec desKeySpec = new DESKeySpec(desKeyData);
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(“DES”);
- SecretKey key = keyFactory.generateSecret(desKeySpec);
Sicurezza Cifratura Simmetrica
Per quanto riguarda la sicurezza per la Crittografia Simmetrica si hanno vari scenari. Per quanto riguarda la Modalità di cifratura la modalità ECB è vulnerabile ad attacchi di crittoanalisi (valutare la frequenza dei blocchi), invece nella modalità CBC questo tipo di attacco non dà nessun risultato. Per quanto riguarda invece l’algoritmo utilizzato il Des è vulnerabile in quanto usa una chiave a 64 bit e si potrebbe effettuare l’attacco del compleanno con un costo computazione di passi. Per risolvere questo problema è stato implementato il TripleDes (DESede) con una chiave a 192 bit, sufficiente a rendere inpraticabile l’attacco del compleanno, però la grandezza del blocco di 64 bit è sempre un limite per questo algoritmo. L’algoritmo più sicuro e più efficiente è AES con la lunghezza del blocco e della chiave a 128 bit.
In allegato una demo realizzata da me:
La relazione dove è presente quest’articolo:
Delitala_Oreste_Crittografia_Java_Relazione
Una breve presentazione sull’argomento: