Capisco che un IV (vettore di inizializzazione) debba essere sia unico che imprevedibile, ma ho trovato poche indicazioni su quale sia il più importante.
Per un codice AES ho una dimensione di blocco di 128 bit da utilizzare. Stavo considerando il seguente schema:
Bit da 0 a 39: meno significativi 40 bit di millisecondi dall'epoca. Questo si ripete all'incirca una volta ogni 34 anni. Un intervallo di tempo che probabilmente supera il tempo in cui i cifrari correnti saranno considerati sicuri e quindi unici nella vita dei dati crittografati.
Bit da 40 a 63: un contatore a 24 bit che inizia con un valore casuale e incrementato per ogni IV. Per garantire univocità solo un thread di esecuzione può accedere al contatore alla volta, e quindi il numero massimo di accessi per millisecondo è limitato dalla velocità di clock di una singola CPU. Questa applicazione verrà utilizzata su CPU normali in cui le velocità di clock sono attualmente al di sotto della velocità di 16 GHz necessaria per esaurire questo contatore entro 1 millisecondo.
Bit da 64 a 95: ho informazioni concatenate sull'hardware e sul processo e poi ho usato un SHA-256 su questi dati. Sto usando i primi 32 bit dell'hash risultante come modo per identificare in modo univoco il processo sorgente. Ciò riduce la possibilità che 2 processi su server diversi possano generare lo stesso IV. Il paradosso del compleanno suggerisce che se ho 65000 processi simultanei, esiste una probabilità 0.5 di due di essi che condividono gli stessi 32 bit qui, ma con il mio massimo previsto di 1000 processi, la probabilità è inferiore a 0,00001.
Bit da 96 a 127: 32 bit casuali estratti da un generatore di numeri casuali sicuro.
Questo IV verrebbe trasmesso insieme al testo cifrato.
La mia prima domanda: questo schema è ragionevole per l'uso con le modalità di cifratura a blocchi: CBC, PCBC, CFB, OFB e CTR?
La mia seconda domanda: c'è qualche vantaggio nel passare i 128 bit attraverso MD5 prima di usarli? Questo sarebbe "migliorare" il IV intrecciando le parti fisse e variabili dell'input.
La mia terza domanda: ahimè, devo anche supportare cifrari a 64 bit come DES, DESede e Blowfish. Non credo che nessun utente utilizzi effettivamente tali codici, ma devono essere supportati. Tali cifre richiedono una semplice IV a 64 bit. Non vedo nulla da quanto sopra che riesco a rimuovere ragionevolmente fornendo ancora garanzie ragionevoli di non ripetibilità e non prevedibilità. Cosa si può fare? Tutto quello che posso pensare di fare è prendere i primi 64 bit di un hash sicuro. È sufficiente?
La mia quarta domanda: solo per CBC, PCBC e CFB, se uso i primi 64 bit come un vero IV, e poi inserisco i secondi 64 bit nel codice come se fossero il primo blocco del messaggio ma scartando il output - funziona così bene come usare un IV a 128 bit anche se la dimensione del blocco della cifra è solo di 64 bit?
Come ulteriore punto, i primi 32 bit del testo normale di alcune decine di messaggi potrebbero essere ragionevolmente noti a un utente malintenzionato. Non sarebbero in grado di controllare gli IV generati per quei messaggi ma potrebbero identificarli in altri modi all'interno di alcune decine di migliaia di messaggi. Il requisito principale di questo sistema di cifratura è di impedire a un attacco con tali informazioni di accedere a qualsiasi parte del testo normale di qualsiasi altro messaggio. Se lo schema IV o le modalità di blocco cifrato che ho menzionato fossero deboli in tale circostanza, sarei grato se la gente potesse indicarlo.