Perché i codici TOTP falliscono quando l’orologio del dispositivo va alla deriva
Il codice è un hash del segreto e del passo temporale corrente. Confronta gli scostamenti su entrambi i lati, poi correggi l’orologio invece di ampliare la finestra.
I codici monouso possono essere perfettamente corretti sul tuo telefono ed essere comunque rifiutati dal server nello stesso secondo. Entrambe le parti calcolano la stessa funzione da un segreto condiviso e dal passo temporale corrente, quindi un disaccordo sull’ora produce un disaccordo sul codice. Questo rende la deriva dell’orologio un guasto rilevante per la sicurezza, non un semplice fastidio.
Qui contano due orologi, e correggere quello visibile è la parte che le persone fanno per prima. Quello che di solito richiede attenzione è l’altro.
Il codice è una funzione del tempo, non una password
TOTP prende il segreto condiviso e un contatore derivato dall’ora corrente, fa passare entrambi attraverso un hash con chiave e tronca il risultato in una breve stringa decimale, come specificato nella RFC 6238. Il contatore avanza a ogni passo temporale, convenzionalmente trenta secondi, quindi lo stesso segreto produce un nuovo valore quando il passo cambia. Il verificatore ricalcola il valore atteso per il passo corrente e confronta, il che richiede lo stesso segreto e la stessa idea di adesso. Una password resta riutilizzabile finché non viene cambiata, mentre questo valore scade su un confine che il client non può vedere.
Per questo un codice funziona e il successivo fallisce pochi istanti dopo. Spiega anche perché copiare un codice da un messaggio di chat sia un’abitudine così inaffidabile.
Due orologi devono essere d’accordo, non uno
Il materiale di registrazione è la prima cosa condivisa, e il tempo è la seconda. Se il segreto è corretto mentre gli orologi differiscono più della finestra tollerata, ogni valore generato finisce nel passo sbagliato e viene rifiutato. Se gli orologi concordano mentre il segreto è errato, anche ogni valore viene rifiutato, e entrambi i guasti appaiono identici dalla schermata di accesso. Separarli significa controllare la voce dell’account e il tempo separatamente, in quest’ordine.
L’orologio del verificatore merita lo stesso esame di quello del dispositivo. Un server la cui fonte di tempo è guasta rifiuta i codici corretti di tutti gli utenti contemporaneamente, e i rapporti descriveranno un’interruzione improvvisa anziché una deriva. Vale la pena riconoscere questo schema, perché la sua correzione spetta al server e non a cento telefoni.
Quanto costa ampliare la finestra
Le implementazioni possono accettare un codice da un passo adiacente per assorbire piccole differenze, e questa tolleranza è una decisione di progetto, non una regolazione gratuita. Ogni passo aggiuntivo moltiplica il numero di valori validi in qualsiasi momento, che è esattamente ciò che preferisce un attaccante che indovina. La regola anti-ripetizione conta per lo stesso motivo, perché un codice accettato due volte è un codice che è trapelato utilmente. Un amministratore che amplia la finestra per zittire le lamentele scambia una proprietà reale con un miglioramento cosmetico.
Correggere l’orologio è la riparazione, mentre ampliare la finestra è un sedativo. Il primo rimuove la causa e il secondo la nasconde.
Controlla entrambi gli orologi prima di riprovare
Leggi l’ora sul dispositivo e sul server, e confronta gli scostamenti invece delle ore locali mostrate. I comandi seguenti mostrano lo stato di sincronizzazione e l’istante UTC grezzo su un host o un server Linux. Eseguili su entrambi i lati prima di modificare qualsiasi impostazione di autenticazione.
timedatectl
date -u +'%Y-%m-%dT%H:%M:%SZ'
chronyc tracking
timedatectl timesync-status
Uno scostamento misurato in secondi è innocuo, uno misurato in minuti spiega un rifiuto, e un sistema che non segnala alcuna fonte di sincronizzazione è candidato a entrambi. Confronta direttamente i due timestamp UTC, poiché l’ora locale include un fuso orario che l’algoritmo non vede mai. Se gli scostamenti sono piccoli e i codici falliscono ancora, smetti di regolare gli orologi e ispeziona invece la voce di registrazione. I tentativi ripetuti contro un account bloccato rendono il guasto originale più difficile da osservare.
Annota l’ora del rifiuto, lo scostamento e il testo dell’errore, e lascia fuori il segreto condiviso. Il supporto può lavorare con i primi tre e non dovrebbe mai vedere il quarto.