Utilizzo di una stringa casuale per autenticare HMAC?

1

Sto progettando un semplice webservice e voglio usare HMAC per l'autenticazione al servizio.

Per lo scopo di questa domanda abbiamo:

  • un servizio web su example.com
  • una chiave segreta condivisa tra un utente e il server [K]
  • un ID utente noto all'utente e al server (ma non necessariamente segreto) [D]
  • un messaggio che vogliamo inviare al server [M]

L'implementazione HMAC standard implicherebbe l'uso della chiave segreta [K] e del messaggio [M] per creare l'hash [H], ma sto riscontrando problemi con questo. Il messaggio [M] può essere piuttosto lungo e tende a essere letto da un file. Ho trovato molto difficile produrre un hash corretto in modo coerente su più sistemi operativi e linguaggi di programmazione a causa di caratteri nascosti che lo rendono in vari formati di file. Questa è ovviamente una cattiva implementazione dal lato client (100%), ma vorrei che questo servizio web fosse facilmente accessibile e non avesse problemi con diversi formati di file.

Stavo pensando ad un'alternativa, che consentirebbe l'uso di una stringa casuale [R] di breve durata (5-10 caratteri) anziché del messaggio per l'autenticazione, ad es.

H = HMAC(K,R)

L'utente passa quindi la stringa casuale al server e il server controlla il lato server HMAC (usando una stringa casuale + segreto condiviso).

Per quanto posso vedere, questo produce i seguenti problemi:

  • Non c'è integrità del messaggio - questa è ok l'integrità del messaggio è non importante per questo servizio
  • Un utente potrebbe riutilizzare l'hash con un messaggio diverso - Posso vedere 2 modi per aggirare questo problema
    1. Combina la stringa casuale con un timestamp in modo che l'hash sia valido solo per un determinato periodo di tempo
    2. Consenti solo che ogni stringa casuale venga utilizzata una volta
  • Poiché il client ha il controllo della stringa casuale, è più semplice cercare le collisioni

Devo sottolineare che il motivo principale per l'autenticazione è l'implementazione della limitazione della velocità sul servizio API. Non c'è bisogno di integrità dei messaggi, e non è un grosso problema se qualcuno può falsificare una singola richiesta (ma lo è se è in grado di falsificare molto velocemente un numero molto grande).

So che la risposta corretta è quella di assicurarsi che il messaggio [M] sia lo stesso su tutte le piattaforme / lingue prima di cancellarlo. Ma, escludendo l'equazione, la proposta sopra è accettabile come seconda migliore?

    
posta mrwooster 24.10.2012 - 02:40
fonte

1 risposta

1

Quindi vuoi votare utenti limite. Non hai davvero bisogno di crittografare il messaggio, allora. Hai bisogno di un bilanciere.

Se ciò è dovuto a problemi di traffico elevato, è meglio implementarlo al di fuori del server e utilizzare sth come haproxy, lighttpd o nginx. Nginx limita per impostazione predefinita le richieste a 50 / minuto per IP e reindirizza a una pagina 503 personalizzabile. Se IP ti si addice come identità, sarà sufficiente.

Se IP non è buono, puoi accettare solo richieste con una chiave solida, quindi utilizzare haproxy come unico bilanciatore, o forse 3scale che fornisce anche analisi.

Se il traffico intenso o il DoS, gli attacchi DDoS sono una preoccupazione per te, puoi anche utilizzare un server Apache con mod_evasive come parte del tuo proxy.

Infine, per essere onesti, ci sono così tante possibilità che l'IP non è un ID affidabile (NAT, utenti che cambiano i loro IP, anche i MAC). Poiché il tuo problema principale sembra essere una soluzione di autenticazione decente, perché non usi OpenID e un sistema di bilanciamento?

Modifica

Nginx ha anche un'opzione limit_proxy_xuid , che può contenere fino a 255 caratteri, per limitare il traffico.

    
risposta data 24.10.2012 - 09:37
fonte

Leggi altre domande sui tag