Questo è in realtà un malinteso comune perché intuitivamente, sembra che l'aggiunta di ritardi casuali dovrebbe contrastare gli attacchi temporali, finché non ci pensi un po 'più a fondo.
In teoria, se le lunghezze dei tuoi ritardi casuali sono illimitate, cioè tratte da [0, infinity]
, allora si sviterebbe un attacco di temporizzazione per il motivo che suggerisci. In pratica tu A) non vuoi che gli utenti legittimi attendono una quantità infinita di tempo per il loro accesso, e B) devono ritirare i tuoi ritardi casuali da qualche intervallo finito [0, a]
. Ciò significa che in media (cioè con abbastanza campioni) stai semplicemente aggiungendo a/2
alla volta.
Quindi diciamo che senza ritardi casuali hai i seguenti profili temporali:
- esegui query sul nome utente esistente: x ms
- query nome utente non esistente: y ms
Con ritardi casuali ora hai (in media):
- esegui query sul nome utente esistente: x + a / 2 ms
- query nome utente non esistente: y + a / 2 ms
Poiché x - y = (x + a/2) - (y + a/2)
, la differenza di temporizzazione è ancora lì per un aggressore da sfruttare. L'unica cosa che hai cambiato è che oltre a dover filtrare il ritardo di rete, il ritardo di schedulazione della cpu, il lag di bilanciamento del carico, ecc., Devono anche filtrare il tuo ritardo casuale a tratti. Un attacco di sincronizzazione di successo sta già facendo più query per ogni nome utente e media, ma ora potrebbe dover aggiungere altri campioni per ottenere la loro media "pulita".
Bottom-line : l'aggiunta di un rumore casuale potrebbe rendere l'attacco più lento, ma non lo renderà più complesso.
L'unico vero modo per proteggersi dagli attacchi temporali è assicurarsi che ogni possibile percorso di codice abbia lo stesso tempo.
- esegui query sul nome utente esistente: x ms
- query nome utente non esistente: x ms
Quindi non c'è davvero modo di distinguere questi due.
Attenzione! La scrittura di codice tempo invariante può essere complicata, da qui la massima "non tirare il tuo". Se riesci a trovare un gestore di accesso che già implementa l'invarianza di temporizzazione, utilizzarlo sarebbe sia più facile che più sicuro.