Le app di OpenSSL devono essere utilizzate con attenzione, spesso hanno impostazioni predefinite vecchie e probabilmente insicure, almeno per gli standard contemporanei.
In questo caso openssl enc
usa per default un digest di MD5 ( apps/enc.c
)
if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
{
BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
goto end;
}
if (dgst == NULL)
{
dgst = EVP_md5();
}
È possibile utilizzare l'opzione% digest del messaggio " -md
" per impostarla in modo esplicito, puoi utilizzare qualsiasi digest supportato come sha256:
openssl enc -md sha256 -e -aes256 -in infile.txt -out outfile.enc -pass pass:foo
Alcune delle tue asserzioni sono corrette, ma non si applicano qui, in particolare poiché un utente malintenzionato non conosce l'output di digest che un attacco di collisione non applica.
Trovare una collisione è utile solo a volte, ad es. quando l'output MD5 viene utilizzato come firma o controllo di integrità. Un attacco di collisione richiede che tu abbia un output hash con cui lavorare.
In questo caso MD5 viene utilizzato come funzione di derivazione della chiave . Per questo, ciò che di solito è più interessante è resistenza pre-immagine : dato un riassunto potresti elaborare un input (es. Password ) che lo genererebbe. MD5 ha una buona resistenza pre-immagine imperfetta, ~ 123 bit anziché 128, vedere RFC6151 .
Dato solo un file crittografato, se il compito dell'aggressore è quello di recuperare i dati crittografati, allora deve scoprire la chiave simmetrica (chiave + IV) utilizzata per crittografare. Questa chiave è anche un riassunto che può calcolare da una pass-frase che può invece scoprire (un sale, se usato, è disponibile nel file).
L'utente malintenzionato non conosce la password o la chiave (digest di sale / password), o lo farà: che è più economico da trovare? Che potrebbe aiutare un utente malintenzionato è se l'output MD5 è distorto, ma non lo è, per quanto ne so.
(Rigorosamente ci possono essere due scenari: recuperare la password per provare qualcosa, non necessariamente accedere ai dati crittografati o solo recuperare la chiave per accedere ai dati crittografati.)
I due attacchi evidenti sono:
- forza bruta dell'intero spazio della chiave (simmetric cipher), se l'output KDF (hash / digest) è distorto, questo sarà più piccolo di quanto dovrebbe essere, il che può aiutare l'autore dell'attacco
- brute-forza lo spazio della password, se l'input è stato scelto da un essere umano allora questo sarà più piccolo dello spazio chiave (il sale eliminerà gli attacchi pre-calcolati, però% di% equi usa un sale casuale per default)
Idealmente, vogliamo un buon KDF senza bias, un output almeno grande quanto l'entropia dell'ingresso atteso, abbinato al keysize del codice simmetrico e costoso in modo che l'attacco n. 2 non offra una scorciatoia.
Usare un digest come MD5 con un output breve (output a 128 bit) come KDF significa che la chiave utilizzata per eseguire la crittografia è solo a 128 bit, e in questo caso non è lunga quanto la tua passphrase richiesta (~ 160 bit, 62 ^ 26). Considerare anche la dimensione della chiave di cifratura simmetrica che verrà utilizzata, idealmente questi dovrebbero essere abbinati.
Il problema maggiore qui non è l'uso potenzialmente problematico di MD5, ma è il KDF che enc
usa è "economico", in particolare usa solo uno round, rendendo gli attacchi di forza bruta sulle password il miglior attacco ( openssl enc
, riga # 569):
EVP_BytesToKey(cipher,dgst,sptr,
(unsigned char *)str,
strlen(str),1,key,iv);
Il sesto parametro per apps/enc.c
(codificato a 1) è il conteggio, progettato per rallentare un attaccante (o no, in questo caso). Quello che dovrebbe essere usato è invece una funzione di allungamento della chiave , come bcrypt o scrypt.