2013-01-24 9 views
5

Ho un codice che sto usando per crittografare e decifrare alcune stringhe in un'applicazione ios. Il codice prevede l'uso di CCCrypt. Esiste un modo affidabile per testare la validità di una chiave utilizzata senza archiviare effettivamente la chiave? Dalla mia ricerca sembra che l'unico modo per avvicinarsi a dire se la chiave è valida è l'utilizzo delle lunghezze delle chiavi e degli hash delle chiavi. Qualcuno può guidarmi nella giusta direzione per questo?Modo affidabile per dire se la chiave errata viene utilizzata nella decrittografia aes256

+1

Si "prova" la validità di una chiave tentando di decrittografare qualcosa crittografato con essa. –

+1

Puoi decifrare qualcosa usando la chiave sbagliata. Non sarà la decrittazione corretta ma la crittografia del testo di input non è lì per confermare la validità della decrittazione. Se il testo di input fosse presente, sarebbe una sorta di sconfiggere l'intero scopo del processo. –

+2

Decifrare qualcosa che puoi riconoscere. –

risposta

6

Per ottenere la risposta è necessario un po 'di informazioni sulla corretta crittografia. Potresti già saperlo, ma la maggior parte delle persone sbaglia tutto, quindi lo sto coprendo. (Se stai crittografando con una password e non codifichi almeno un HMAC, due sali e un IV, stai sbagliando.)

In primo luogo, devi usare un HMAC (vedi CCHmac()) qualsiasi tempo di crittografia con una modalità non autenticata (come AES-CBC). In caso contrario, gli utenti malintenzionati possono modificare il testo cifrato in modo da farlo decrittografare in un messaggio diverso. Vedi modaes per un esempio di questo attacco. Un HMAC è un hash crittograficamente sicuro basato su una chiave.

In secondo luogo, se si utilizza la crittografia basata su password, è necessario utilizzare un KDF per convertirlo in una chiave. Il più comune è PBKDF2. Non puoi semplicemente copiare i byte della password in una chiave.

Supponendo che si utilizzi una password in questo modo, in genere si generano due chiavi, una per la crittografia e una per HMAC.

OK, con quelle parti sul posto, è possibile verificare che la password sia corretta perché l'HMAC avrà esito negativo se non lo è. Questo è il modo in cui lo fa RNCryptor.

Ci sono due problemi con questo approccio semplice: è necessario elaborare l'intero file prima di poter verificare la password, e non c'è modo di rilevare la corruzione del file rispetto alla password errata.

Per risolvere questi problemi in qualche modo, è possibile aggiungere un piccolo blocco di dati aggiuntivi che si HMAC separatamente.Quindi si verifica quel blocco piccolo anziché l'intero file. Questo è fondamentalmente come lo fa . In particolare, generano una chiave "reale" per crittografare l'intero file e quindi crittografano quella chiave con una chiave generata da PBKDF2 e HMAC separatamente. Alcune forme di corruzione sembrano ancora cattive password, ma è un po 'più facile distinguerle in questo modo.

+0

Cosa ne pensi del seguente processo: utilizzo la chiave per crittografare se stessa e archiviarla con il resto delle informazioni crittografate. Quando l'utente fornisce una chiave per decrittografare le informazioni, crittografo la chiave fornita con se stessa e controlla se corrisponde alla chiave crittografata. Se lo fa, posso quindi andare avanti con la decrittografia dei dati usando la chiave fornita dall'utente. –

+0

Se progettato correttamente, potrebbe essere ok (anche se senza un HMAC, sei comunque suscettibile di manipolazione nel tuo testo cifrato, quindi in genere ne avrai comunque bisogno). Vorresti assolutamente un IV casuale prima della chiave. Non so se sarebbe meglio di un insieme di byte fissi noti all'inizio del messaggio. Dovrei pensarci. –

+0

Bene, grazie per l'aiuto, ho dato un'occhiata alla classe RNCryptor e probabilmente lo userò, sembra fare tutto ciò che voglio da ciò che ho letto nella sua documentazione. –

0

È possibile memorizzare un valore noto crittografato con la chiave nel database. convalidare se la chiave è corretta è quindi semplice: si cripta la stringa conosciuta e la si confronta con l'output crittografato nel database. Se ti attacchi con un singolo blocco di dati, non devi preoccuparti delle modalità operative e puoi mantenerlo semplice.

È anche possibile memorizzare un hash della chiave, ma considererei la chiave come una password e prendere tutte le misure difensive che occorrerebbe per memorizzare una password nel database (ad esempio, utilizzare bcrypt, sale l'hash , eccetera).

Se non è possibile memorizzare questi valori, è possibile decrittografare qualcosa in cui non si conosce il contenuto effettivo, ma forse conoscere alcune proprietà del messaggio (ad esempio testo ASCII, data di oggi in qualche punto della stringa, ecc.) e testare il messaggio decrittografato per tali proprietà. Quindi se il blocco decrittografato che non ha quelle proprietà (ad esempio ha byte con MSB impostato, nessuna istanza della data), si sa che la chiave non è valida. C'è una possibilità di un falso positivo in questo caso, ma le probabilità sono molto basse.

0

Generalmente sono d'accordo con Peter Elliott. Tuttavia, ho paio di commenti aggiuntivi:

a) Se i tasti sono stati generati in modo casuale quindi la memorizzazione hash delle chiavi sono sicuri

b) È sempre possibile allegare al messaggio criptato (se è possibile controllare che) un hash di messaggio originale. In tal caso, è possibile decodificare il messaggio, ottenere l'hash del messaggio decrittografato e confrontarlo con l'hash del messaggio originale. Se sono eqaul, la chiave corretta è stata utilizzata per la decrittazione.

Problemi correlati