Come garantire la sincronizzazione dei contatori tra client e server per il conteggio nell'implementazione della password una tantum basata su hmac?

2

Questo è un clone di una domanda che ho postato su Stack Exchange. Ho pensato che avrei potuto catturare l'attenzione di alcune persone diverse che potrebbero aiutarti qui.

Stiamo cercando di implementare un protocollo di password monouso basato su hmac per utilizzare l'autenticazione degli utenti sulla nostra API.

L'idea è di crittografare un identificatore univoco per l'utente (uid) contro una chiave privata e un contatore incrementale. Quindi incrementa il contatore per la prossima chiamata.

encrypt(uid, private_key, counter)
# now increment the counter for the next call

Quindi sul lato server, decrittografare utilizzando la chiave privata e il contatore per ottenere l'identificativo utente (uid).

decrypt(encrpyted_string, private_key, counter)
# now increment the counter for the next received request

Funziona bene. Ogni chiamata è completamente unica (una volta) a causa del contatore.

Tuttavia come gestiremo la sincronizzazione del contatore? Cosa succede se il client genera una richiesta, incrementa il contatore per la prossima chiamata e invia la richiesta, ma il server è offline e non riceve mai la richiesta, oppure c'è un problema di connettività Internet e la richiesta non arriva mai: ora il server e il client non è sincronizzato con i contatori reciproci.

Si tratta di un caso di "dovresti sapere se è stata inoltrata una richiesta"? Cioè potremmo aggiungere un'intestazione di risposta dal server per dire se il contatore è stato incrementato e solo se lo ha fatto incrementiamo il contatore anche nell'app ... ma poi lo stesso si potrebbe dire al contrario - potremmo inviare un richiesta, il server la riceve, incrementa il proprio contatore e invia una risposta, ma la connessione Internet è stata interrotta mentre il server stava elaborando la sua richiesta e l'app non riceve mai la risposta, non incrementa mai il suo contatore e quindi i due non sono sincronizzati ancora una volta.

Grazie per le informazioni che mi puoi dare.

    
posta Thomas Clayson 21.03.2013 - 18:35
fonte

2 risposte

3

Vedi HOTP , sezione E.4 . Questo è ragionevolmente ben spiegato. La sostanza della soluzione: quando il contatore sul server contiene n , il server accetta effettivamente come valide le password monouso corrispondenti ai valori n , n + 1 , n + 2 ... fino a (diciamo) n + 99 . Se ciò che il client ha inviato corrisponde alla password monouso per il valore n + 37 , il client viene accettato e il nuovo valore del contatore nel server è impostato su n + 38 . La larghezza dell'intervallo accettato dal server è un compromesso: una gamma più ampia sopporta i client che sono ampiamente fuori sincrono, ma è più costoso sul lato server (più potenziali password monouso da calcolare) e diminuisce la sicurezza ( dal momento che più password distinte saranno, in qualsiasi momento, ritenute "accettabili").

    
risposta data 21.03.2013 - 19:19
fonte
2

Tipicamente la soluzione per questo è o per a) controllarla rispetto ai valori andando avanti per vedere se questo si è verificato e incrementare di conseguenza se si è scoperto che è andato alla deriva. (Questo è il modo in cui i token basati sul tempo rappresentano la deriva del clock.) O b) se i sistemi possono interagire, fare uno scambio del valore del contatore corrente su entrambi i sistemi. Possono essere d'accordo su qualunque sia l'ultimo valore usato e usarlo. Vale la pena notare che senza un limite di tempo, tuttavia, la riproduzione sarà possibile in quanto un sito di phishing potrebbe richiedere il codice successivo e quindi utilizzarlo per parlare con il server. Un sistema basato sul tempo limiterebbe la finestra di opportunità per tale attacco per garantire che l'utente stia cercando di andare avanti in quel momento e quindi noterebbe (si spera) che la sua sessione legittima venga respinta.

    
risposta data 21.03.2013 - 19:11
fonte

Leggi altre domande sui tag