Vorrei un feedback sulla seguente idea di autenticazione, ha senso e c'è uno standard modo di fare questo (o simili) così posso fare affidamento su un'implementazione ben testata.
Ho visto molte risposte qui su come proteggere la comunicazione con il server, e la maggior parte delle risposte sono semplicemente usa TLS correttamente. Sto cercando una soluzione che consenta la crittografia e la firma dei messaggi stessi, quindi il messaggio rimane al sicuro mentre attraversano il back-end, fino a quando raggiungono il servizio di destinazione.
Contesto
- App per dispositivi mobili per Android 2.3+ e iOS 6+ creati con phonegap (quindi le librerie usate dovrebbero essere utilizzabili da Java / obj-c o js)
- L'app comunica con il server utilizzando un REST json api
- Il contenuto del messaggio deve rimanere confidenziale mentre attraversa il back-end (nessuna terminazione su proxy / bilanciamento del carico)
- Dovrebbe supportare "ricordami", quindi l'utente non deve inserire nuovamente la passphrase per tutto il tempo
- Tutte le comunicazioni sono fatte su ssl / tls
Autenticazione
- il client raccoglie le credenziali dell'utente (nome utente, passphrase e alcune informazioni di sicurezza aggiuntive)
- il client genera una chiave simmetrica
- il client crittografa le credenziali con la chiave simmetrica
- il client crittografa la chiave simmetrica con la chiave pubblica del server (fornita con il client)
- il client invia il messaggio crittografato, chiave e nonce tramite https (convalida del certificato del server)
- il proxy server inoltra la richiesta di autenticazione al servizio di autenticazione
- il servizio di autenticazione decrittografa la chiave simmetrica e il messaggio
- se le credenziali sono valide, il servizio genera un token di autenticazione
- il token è associato alla chiave simmetrica sul server, se le credenziali non sono valide, la chiave viene scartata dopo aver risposto alla richiesta
- il token viene restituito all'utente, crittografato con la chiave simmetrica
- il token e la chiave sono memorizzati localmente sul client, crittografati da una breve password
Suppongo che queste richieste siano al riparo dagli attacchi di ripetizione se si utilizza tls, quindi non c'è il rischio che un utente malintenzionato riesegua il messaggio per ottenere un nuovo token.
Altre chiamate API
- il client genera i messaggi di richiesta, lo crittografa e firma il messaggio crittografato
- il client invia il messaggio crittografato, nonce e firma con il suo token di autenticazione al server
- alla ricezione il server cerca la chiave associata al token ricevuto, verifica la firma e decrittografa il messaggio prima di elaborarlo
Domande
- c'è qualche problema con il riutilizzo della stessa chiave simmetrica?
- qual è una buona scelta di chiave simmetrica?
- Che dire di AES-OCB o AES-CBC + firma HMAC?
- quanto spesso dovrebbe essere cambiata la chiave simmetrica?
- Qual è il modo migliore di aggiornare la chiave / i token di aggiornamento? Stavo pensando di emettere un token di aggiornamento durante la risposta di autenticazione e le chiavi scadono dopo un periodo specifico, quindi se l'utente non aggiorna le proprie chiave devono accedere nuovamente.
Grazie