Cifratura Cifratura simmetrica Alice canale insicuro Bob 2 Cifratura simmetrica Algoritmo di decifratura m m Alice canale insicuro Algoritmo di cifratura Bob 3 Cifrari simmetrici chiave privata k chiave privata k C ← CIFRA(k,M) CIFRA M ← DECIFRA(k,C) DECIFRA C Alice canale insicuro Bob messaggio M 4 Cifrario di Cesare 100-44 a.C. Svetonio (Vitae Caesarorum): lettera di Cesare a Cicerone A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 testo in chiaro X ← M+3 mod 26 OMNIA GALLIA EST DIVISA IN PARTES TRES RPQLD JDOOLD HVW GLYLVD LQ SDUWHV WUHV testo cifrato 5 Cifrari con shift A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Chiave K X ← M+K mod 26 K∈{0,1,…,25} 6 Cifratura di dati testuali Scriviamo un programma che Legge da un file di testo, un carattere alla volta Cifra un carattere alla volta, usando un cifrario con shift Scrive in un file i caratteri cifrati, uno alla volta 7 Cifratura di dati testuali int next = in.read(); //leggi il prossimo char if (next == -1) done = true; else //il file non è terminato { char b = (char)next; //converti in char char c = encrypt(b); //cifra il char out.write(c); //scrive il char cifrato } 8 File Shift.java import java.io.*; public class Shift { /** Costruisce un cifrario con shift. @param aKey la chiave di cifratura public Shift(int aKey) { if (aKey >25) throw new NumberFormatException("La chiave deve essere un intero tra 1 e 25"); else key = aKey; } 9 /** Cifra il contenuto di un file. @param inFile il file di ingresso @param outFile il file di uscita */ public void encryptFile(File inFile, File outFile) throws IOException { Reader in = null; Writer out = null; try { in = new FileReader(inFile); out = new FileWriter(outFile); encryptCharStream(in, out); } finally { if (in != null) in.close(); if (out != null) out.close(); } } 10 /** Cifra il contenuto di un flusso. @param in il flusso di ingresso @param out il flusso di uscita */ public void encryptCharStream(Reader in, Writer out) throws IOException { boolean done = false; while (!done) { int next = in.read(); if (next == -1) done = true; else { char b = (char)next; char c = encrypt(b); out.write(c); } } } 11 /** Cifra un char. @param b il char da cifrare @return il char cifrato */ public char encrypt(char b) { String s = "abcdefghijklmnopqrstuvwxyz"; int i = 0; while (i < 26) { if (b == s.charAt(i)) return s.charAt((i + key +26)%26); else if (b == Character.toUpperCase(s.charAt(i))) return Character.toUpperCase(s.charAt((i+ key +26)%26)); i++; } return b; } private int key } 12 Argomenti sulla riga di comando Scriviamo un programma Crypt che testa la classe Shift Legge il nome del file da cifrare e la chiave di cifratura dalla riga di comando 13 Argomenti sulla riga di comando Argomenti accettati -d per indicare la decifratura -k per indicare la chiave (3 di default) Il nome del file input Il nome del file output Esempio: java Crypt input.txt encrypt.txt java Crypt –d –k11 encrypt.txt output.txt 14 Argomenti sulla riga di comando 15 File Crypt.java import java.io.File; import java.io.IOException; public class Crypt { public static void main(String[] args) { boolean decrypt = false; int key = DEFAULT_KEY; File inFile = null; File outFile = null; if (args.length < 2 || args.length > 4) usage(); 16 try { for (int i = 0; i < args.length; i++) { if (args[i].charAt(0) == '-') { // è un’opzione della riga comandi char option = args[i].charAt(1); if (option == 'd') decrypt = true; else if (option == 'k') key = Integer.parseInt(args[i].substring(2)); } 17 else { // è il nome di un file if (inFile == null) inFile = new File(args[i]); else if (outFile == null) outFile = new File(args[i]); else usage(); } } if (decrypt) key = -key; Shift crypt = new Shift(key); crypt.encryptFile(inFile, outFile); } catch (NumberFormatException exception) { System.out.println(exception); } 18 catch (IOException exception) { System.out.println("Errore nel processare il file: " + exception); } } /** Stampa un messaggio che descrive l’uso corretto, poi termina il programma. */ public static void usage() { System.out.println( "Utilizzo: java Crypt [–d] [–kn] infile outfile"); System.exit(1); } public static final int DEFAULT_KEY = 3; } 19 Cifratura di dati binari Scriviamo un programma che Legge da un file dati binari, un byte alla volta Cifra i dati, un byte alla volta, usando un cifrario con shift Scrive in un file i byte cifrati, uno alla volta 20 Cifratura di dati binari int next = in.read(); //leggi il prossimo byte if (next == -1) done = true; else //il file non è terminato { byte b = (byte)next; //converti in byte byte c = encrypt(b); //cifra il byte out.write(c); //scrive il byte cifrato } 21 File Shift.java import java.io.*; public class Shift { /** Costruisce un cifrario con shift. @param aKey la chiave di cifratura public Shift(int aKey) { key = aKey; } 22 /** Cifra il contenuto di un file. @param inFile il file di ingresso @param outFile il file di uscita */ public void encryptFile(File inFile, File outFile) throws IOException { InputStream in = null; OutputStream out = null; try { in = new FileInputStream(inFile); out = new FileOutputStream(outFile); encryptStream(in, out); } finally { if (in != null) in.close(); if (out != null) out.close(); } } 23 /** Cifra il contenuto di un flusso. @param in il flusso di ingresso @param out il flusso di uscita */ public void encryptStream(InputStream in, OutputStream out) throws IOException { boolean done = false; while (!done) { int next = in.read(); if (next == -1) done = true; else { byte b = (byte)next; byte c = encrypt(b); out.write(c); } } } 24 /** Cifra un byte. @param b il byte da cifrare @return il byte cifrato */ public byte encrypt(byte b) { return (byte)(b + key); } private int key; } 25