Abbiamo una situazione in cui l'identità dell'utente può essere verificata come segue: il provider di rete conosce l'identità dell'utente e inietta intestazioni sicure nella richiesta HTTP, che i nostri server possono utilizzare per autenticare l'utente.
Stiamo scrivendo applicazioni client-server e vogliamo utilizzare questo meccanismo per autenticare automaticamente l'utente. Non possiamo utilizzare HTTPS end-to-end per la richiesta di autenticazione perché ovviamente la rete non può iniettare intestazioni in quel caso.
MODIFICA: impostazione approssimativamente equivalente:
(client < -VPN- > proxy HTTP) < -internet- > il nostro server
Supponiamo che la VPN (sezione in grassetto) sia sicura e l'utente sia autenticato all'interno della VPN.
Il client genera una richiesta HTTP. Un proxy all'interno della rete conosce l'identità del client e genera un token che viene automaticamente aggiunto alle intestazioni nella richiesta HTTP proxy. Tutto ciò accade in un dominio sicuro e non può quindi essere compromesso. (Sfortunatamente non possiamo cambiare nulla nella configurazione VPN, come invece il proxy fare una richiesta HTTPS.)
Il nostro server può eseguire query sulla rete (in modo sicuro) per determinare l'identità del client che ha avviato la richiesta.
Ipotesi:
- Questo requisito HTTP è un dato e non può essere modificato.
- Un utente malintenzionato non può ingannare il processo di verifica dell'identità presentando intestazioni false.
- Un utente malintenzionato potrebbe essere in grado di intercettare / compromettere la richiesta / risposta HTTP.
- Il server è stateless (quindi non si memorizzano chiavi one-time sul lato server).
- L'archiviazione di una chiave privata nell'applicazione client non è un'opzione in quanto potrebbe essere compromessa
- La richiesta / risposta HTTP verrà utilizzata per autenticare automaticamente l'utente, ma tutte le altre interazioni prima (se necessario) e in seguito saranno su HTTPS.
Ecco cosa abbiamo provato finora:
- Il cliente recupera una chiave pubblica
PK
dal server su HTTPS - Il client genera una chiave simmetrica
SK
- Il client crittografa
SK
utilizzandoPK
e lo invia al server su HTTP - Il server verifica l'identità dell'utente e genera il token di autenticazione
AT
- Il server crittografa
AT
usandoSK
- > %codice% - Il server firma
E(AT,SK)
utilizzando la sua chiave privata e invia al client - Il client utilizza
E(AT,SK)
per verificare la firma - Il client utilizza
PK
per decrittografareSK
dandoE(AT,SK)
- Il client utilizza
AT
per autenticare tutto il traffico HTTPS successivo.
(E dovremmo probabilmente usare coppie di chiavi separate per la crittografia e la firma, ma per ora ignoriamolo).
Per quanto posso vedere, questo è sicuro contro gli intercettatori (dato che non avranno AT
) ma se un malintenzionato può modificare la richiesta HTTP, non c'è nulla che impedisca loro di generare la propria chiave simmetrica invece di SK
, crittografandolo con SK
, sostituendo il carico utile della richiesta con quello e il server non avrà idea che non stia parlando con il vero client. Il server quindi crittograferà felicemente un PK
valido e lo rimanderà all'attaccante che potrà quindi procedere con impunità.
C'è un modo per puntellare questo buco? È persino possibile farlo con un server stateless?
EDIT: se il server è in grado di rilevare manomissioni e interrompere il processo di autenticazione, ciò sarebbe sufficiente. "Questo non è possibile perché X" è anche una risposta valida, se può essere dimostrata.