TLDR: la crittografia insicura non è nemmeno sicura se non riesci a vedere il valore crittografato.
Gli altri post spiegano bene molte delle ragioni per cui non dovresti scrivere la tua crittografia, in un ambiente in cui l'attaccante può vedere il valore crittografato, ma perde qualcosa di veramente importante: non dovresti nemmeno scrivere la tua crittografia quando l'aggressore non può vedere il messaggio crittografato.
C'è questa cosa chiamata "canale laterale". I canali secondari sono (di solito 1 ) cose non intenzionali che perdono informazioni su ciò che sta facendo la tua applicazione. Ad esempio, forse sono necessari più cicli della CPU - e quindi più tempo - per confrontare una password parzialmente corretta con il valore 2 "cifrato". Ciò consentirebbe a un utente malintenzionato di accelerare un attacco di forza bruta per apprendere lentamente la password corretta.
Facciamo un esempio ingenuo. Facciamo finta che ci voglia 1 secondo per testare un singolo carattere della password inviata rispetto al valore memorizzato nel database. Immagina che la password corretta sia lunga 8 caratteri e che una password non valida venga rifiutata al primo risultato errato. L'algoritmo potrebbe avere un aspetto simile a:
booleano encrypt_password (stringa password) {if (non isascii (password)) {return false; } // ERRORE! risultato stringa; foreach (char c: password) {result + = daves_magic_that_takes_1s (c)} return true;} boolean is_correct_password (input, pw_from_db) {if (input.length! = pw_from_db.length) {return false} foreach (char c_in, c_db: input, password) {c_in = daves_magic_that_takes_1s (c_in) if (c_in! = c_db) {return false}} return true; // password valida!}
Ora, immaginiamo che la password valida sia "password" e che l'aggressore provi a inserire "a". Questo non riesce, perché le password sono di lunghezza errata. L'aggressore può provare a caso varie password. Ogni password errata più lunga o più corta di "password" richiede meno di un secondo per l'elaborazione. Diciamo che presto provano "12345678". "12345678" ha la stessa lunghezza di "password" quindi richiede un secondo per l'elaborazione. Il tempismo è diverso e l'attaccante se ne accorge. Tentano più volte di verificare ed è coerente.
L'aggressore ora prova diverse password di 8 caratteri. Tutti impiegano 1 secondo. L'aggressore ha scoperto un canale laterale che gli dice che la password valida è probabilmente lunga 8 caratteri. Ora devono determinare quale password di 8 caratteri è quella giusta.
L'aggressore inizia a provare casualmente password di 8 caratteri. Alla fine, provano "p2345678" e notano che ci vogliono 2 secondi per completare. Testano un sacco e scoprono che tutti i tentativi che iniziano con "p" richiedono 2 secondi per essere completati. L'aggressore ipotizza che l'algoritmo abbia un canale laterale che gli dice quanti caratteri ha corretti.
Ora, invece di dover tentare tutte le 96 ^ 8 password per forzare quella valida, l'attaccante ha solo per provare 96 * 8 password 3 . A seconda di quante password possono essere testate in parallelo, probabilmente possono forzare con successo la password in un tempo molto ragionevole. Questo è fantastico per l'attaccante! Ed è terribile per la sicurezza del tuo sistema. 4
Come proteggiamo dai canali secondari di temporizzazione? Garantiamo che tutte le operazioni in cui la tempistica potrebbe trapelare informazioni sensibili DEVONO sempre richiedere lo stesso tempo per essere eseguite.
Questo potrebbe sembrare un esempio molto semplice. È successo in natura. La ricerca di NVD per "canale laterale di temporizzazione" ti consentirà di ottenere molte vulnerabilità del mondo reale che producono tutte lo stesso tipo di risultati, consentendo a un utente malintenzionato di apprendere informazioni segrete a cui non è autorizzato. Per definizione, se tutte le operazioni richiedono la stessa quantità di tempo indipendentemente dall'input, la quantità di tempo impiegata da qualcosa non ti dice nulla sull'input.
Nel mondo reale, i canali laterali sono incredibilmente facile da introdurre. Dave probabilmente non ne ha nemmeno sentito parlare, ed è probabilmente un buon ingegnere interessato alle prestazioni del suo sistema, che in realtà è un anti-pattern per la protezione dai canali laterali. L'algoritmo di Dave può benissimo avere canali secondari sia ovvi che sottili che non scoprirà mai, ma che i ricercatori e gli aggressori sanno cercare e possono scrivere abbastanza facilmente test automatici per rilevarli. 5
Quindi, solo perché non puoi vedere la crittografia non significa che non puoi vedere gli effetti collaterali della crittografia cattiva e utilizzare questi effetti collaterali per apprendere il segreto protetto.
Endnotes
1: Beh, se sei un agente dell'intelligence o un bravo giornalista di giornali, probabilmente hai intenzionalmente organizzato canali laterali in modo da poter comunicare con i tuoi agenti / fonti senza che "il nemico" lo sappia. Allo stesso modo, se sei subdolo, potresti creare un protocollo crittografico con un canale laterale al suo interno con l'intenzione di far trapelare informazioni segrete.
2: poiché possiamo e dobbiamo sempre presumo che la crittografia personalizzata non sia sicura (per i motivi che altri hanno menzionato in questo thread e altro), probabilmente non dovremmo chiamare l'uso di algoritmi di crittografia personalizzati "crittografia" o "decrittografia" ... forse "crittografia insicura" o "decrittografia interrotta "...
3: Ignoro gli attacchi di forza bruta che riescono, in media, quando l'attaccante ha provato il 50% + 1 password, per semplicità di descrizione. Mi sto concentrando sui canali laterali, non sugli attacchi di forza bruta. Sorvolo anche sui calcoli di un attacco di forza bruta, poiché è anche tangenziale all'argomento principale; un po 'di Google-Fu per conto del lettore dovrebbe individuare molte risorse che vanno in profondità nei dettagli.
4: "1 secondo è troppo lento", giusto? Nessun sistema del mondo reale potrebbe essere controllato per i canali secondari di temporizzazione del mondo reale su Internet, giusto? Sbagliato. Non ho i riferimenti a portata di mano, ma ci sono state ricerche per un certo numero di anni che hanno dimostrato che è possibile testare statisticamente i tempi nell'ordine dei millisecondi su transazioni HTTP.
5 In effetti, sarei pronto a scommettere che ci sono framework o strumenti esistenti (molto probabilmente entrambi) che puoi utilizzare per testare la tua applicazione per ovvi canali secondari, se dovessi esercitare il tuo Google-Fu. sup>