Classi Java per la protezione della riservatezza Tecnologie per la Sicurezza L-S AA 2006-2007 Anna Riccioni [email protected] Cifratura e decifrazione • Classe Cipher (javax.crypto) – Creazione istanza • Cipher c = Cipher.getInstance(“TripleDES/ECB/PKCS5Padding”); • Cipher c = Cipher.getInstance(“TripleDES/CBC/PKCS5Padding”, “BC”); – Inizializzazione • c.init(Cipher.ENCRYPT_MODE, key); • c.init(Cipher.ENCRYPT_MODE, key, initVect); Cifratura e decifrazione • Classe Cipher (javax.crypto) – Alimentazione input (se non è completo nel momento in cui si inizia la cifratura) • int ctLen = c.update(input, 0, input.length, cipherText, 0); – Completamento processo • c.doFinal(input); • int ctLen += c.doFinal(cipherText, ctLen); Chiavi segrete random: generazione automatica • Classe KeyGenerator (javax.crypto) – Creazione istanza • KeyGenerator kGen = KeyGenerator.getInstance(“TripleDES”); • KeyGenerator kGen = KeyGenerator.getInstance(“TripleDES”, “BC”); – Inizializzazione • kGen.init(112); – Generazione chiave • Key k = kGen.generateKey(); Chiavi segrete random: generazione automatica • Classe SecureRandom (java.security) – Genera byte (pseudo)casuali – Creazione istanza • SecureRandom sRand = SecureRandom.getInstance(“SHA1PRNG”); • SecureRandom sRand = SecureRandom.getInstance(“SHA1PRNG”, “BC”); – Inizializzazione • sRand.setSeed(seed); • Inizializzazione forzata, basata su byte random precedentemente raccolti. In alternativa, l’oggetto può inizializzare autonomamente il proprio stato (meno efficiente) Chiavi segrete random: generazione automatica • Classe SecureRandom (java.security) – Creazione di byte random • byte[] randByte = new byte[20]; • sRand.nextBytes(randByte); – Creazione di byte di seed • byte[] seed = sRand.generateSeed(20); • genera il numero di byte di seed richiesto, utilizzando l’algoritmo di generazione del seme che l’oggetto SecureRandom usa per inizializzare se stesso Chiavi segrete random: generazione semi-automatica • Classe SecretKeySpec (javax.crypto.spec) – Converte un array di byte in un oggetto Key che può essere passato ad una istanza di Cipher – Utilizzo (array noto) • byte[] keyBytes = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }; • SecretKeySpec key = new SecretKeySpec(keyBytes, “AES”); Chiavi segrete random: generazione semi-automatica • Classe SecretKeySpec (javax.crypto.spec) – Converte un array di byte in un oggetto Key che può essere passato ad una istanza di Cipher – Utilizzo (array non noto, generato con byte casuali) • SecureRandom sRand = SecureRandom.getInstance(“SHA1PRNG”); • byte[] keyBytes = new byte[24]; • sRand.nextBytes(keyBytes); • SecretKeySpec key = new SecretKeySpec(keyBytes, “AES”); Vettore di inizializzazione • Classe IVParameterSpec (javax.crypto.spec) – Converte un array di byte in un vettore di inizializzazione che può essere passato ad una istanza di Cipher – Utilizzo (array non noto, generato con byte casuali) • SecureRandom sRand = SecureRandom.getInstance(“SHA1PRNG”); • byte[] ivBytes = sRand.generateSeed(8); • IVParameterSpec key = new IVParameterSpec(ivBytes); Chiavi segrete: generazione basata su password • Classe PBEParameterSpec (javax.crypto.spec) – Utilizzo • • • • • char[] pwd = “password”.toCharArray(); byte[] salt = sRand.generateSeed(8); int iterCount = 2048; PBEKeySpec pbeKey = new PBEKeySpec(pwd); SecretKeyFactory kFact = SecretKeyFactory.getInstance(“PBEWithSHAAnd3Key TripleDES”, “BC”); • Cipher c = Cipher.getInstance(“PBEWithSHAAnd3Key TripleDES”, “BC”); • Key key = kFact.generateSecret(pbeKey); • c.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(salt, iterCount)); Passaggio delle chiavi • Recupero dei byte di chiave e ricostruzione – Modalità meno portabile (piattaforme diverse possono effettuare ricostruzioni diverse) • • • • Key key = keyGen.generateKey(112); byte[] keyBytes = key.getEncoded(); .... SecretKeySpec key = new SecretKeySpec(keyBytes, “TripleDES”); Passaggio delle chiavi • Wrapping / unwrapping della chiave – Modalità più portabile e sicura • KeyGenerator keyGen = KeyGenerator.getInstance(“AES”, “BC”); • Key key = keyGen.generateKey(128); • Cipher c = Cipher.getInstance(“AESWrap”, “BC”); • Key wrapKey = keyGen.generateKey(256); • c.init(Cipher.WRAP_MODE, wrapKey); • byte[] wrappedKeyBytes = c.wrap(key); • .... • c.init(Cipher.UNWRAP_MODE, wrapKey); • Key key = c.unwrap(wrappedKeyBytes, “AES”, Cipher.SECRET_KEY); Passaggio dei dati • Dati semplici (file) – Convertiti in array di byte, tenendo conto delle specifiche codifiche, e successivamente cifrati • byte[] input = plaintext.getBytes(“UTF-8”); • .... • byte[] ciphertext = c.doFinal(input); Passaggio dei dati • Dati complessi (oggetti serializzabili) – Un SealedObject incapsula un oggetto serializzabile cifrato ed il cifrario utilizzato • Cipher c = Cipher.getInstance(“DES/ECB/PKCS5Padding”, “BC”); • c.init(Cipher.ENCRYPT_MODE, desKey); • SealedObject so = new SealedObject(obj, c); • Cifra l’oggetto e lo incapsula all’interno del SealedObject assieme al cifrario utilizzato. Il SealedObject può poi essere trattato come ogni altro oggetto (serializzato, scritto su file, …)