Questa soluzione di autenticazione e crittografia è sicura?

3

Ho bisogno di comunicare su socket TCP insicuri dove SSL / TLS non è disponibile. La seguente soluzione fornisce un mezzo sicuro di autenticazione e crittografia?

-

  1. Il client invia: nome utente
  2. Il server genera un token casuale (31 byte).
  3. Il server recupera una password salt and hash (bcrypt) dal database per il nome utente specificato.
  4. Server crittografa il token casuale tramite l'hash della password.
  5. Il client riceve: passwordSalt + encryptAes (token, passwordHash)
  6. Il client ottiene la passwordHash usando bcrypt sulla password e la password ricevuta salt.
  7. Il client ottiene il token decodificando il token crittografato con l'hash della password.
  8. Il client genera una "validazione" casuale (15 byte).
  9. Il client genera un hash del token utilizzando il sale di convalida e lo crittografa con il token.
  10. Il client invia: encryptAes (validationSalt + md5 (token + validationSalt), token)
  11. Il server ottiene l'hash decrittandolo con il token.
  12. Il server confronta se l'hash ricevuto è uguale a md5 (token). Se sono uguali, il client è stato autenticato.
  13. Il server genera un hash dell'hash della password utilizzando il sale di convalida, lo riempie con 15 byte casuali e lo crittografa con il token.
  14. Il client riceve: encryptAes (randomBytes (15) + md5 (passwordHash + validationSalt), token)
  15. Il client ottiene l'hash decodificandolo con il token.
  16. Il client confronta l'hash con md5 (passwordHash + validationSalt). Se sono uguali, il server è stato autenticato.

Tutti i dati verranno ora crittografati con il token generato dal server.

-

Il server è in Java, i client sono in C ++ (UE4).

La crittografia a chiave pubblica non è attualmente disponibile.

-

C'è qualche difetto o debolezza in questa soluzione?

    
posta Zwarmapapa 14.03.2016 - 16:36
fonte

3 risposte

3

In pratica hai creato uno schema di autenticazione segreta condiviso.

Tuttavia, non hai definito quali sono i tuoi obiettivi di sicurezza. Autenticazione di entità, autenticazione con entità strong, riservatezza, anonimato, ...? Quindi è difficile dire "(sì / no), questo è (non) sicuro". Se i tuoi obiettivi di sicurezza non erano i precedenti, probabilmente questo è sicuro. Ma non vorrei usare questa cosa (spero non ti dispiaccia)! : -)

Sembra che tu pensi che la chiave di autenticazione sia la password. Tuttavia, questo non è il caso in quanto la conoscenza dell'hash dal database è sufficiente per autenticare con successo. Provalo e gioca al client che conosce solo l'hash della password e vedrai che funziona.

Il problema qui è che non hai specificato quale sia esattamente il segreto. Sapendo che puoi rendere l'intero processo molto più semplice. Si supponga che il segreto sia l'hash dal database e si desidera autenticare l'utente sul server:

  • Il server genera una chiave di sessione e un numero casuale, crittografa entrambi con il segreto e lo invia al client
  • Il client genera il segreto condiviso chiedendo la password
  • Il client decrittografa la chiave di sessione
  • Il client aggiunge 1 al numero casuale, lo crittografa con la chiave di sessione e lo invia al server

Come puoi vedere, la sicurezza si basa ancora sulla conoscenza dell'hash dal database, ma impostare un segreto condiviso e autenticare il client è diventato molto più semplice. Si prega di notare che questo è ancora lontano dall'essere sicuro! Volevo solo dimostrare che le cose spesso non sono ciò che sembrano. Giocare con i sali non rende le cose necessariamente migliori.

Il punto è: Complicato non significa sicuro, e - come sottolineato prima - non ti fidi della tua crittografia fatta da te; -)

Modifica : solo per la cronaca, pensa a oracoli, attacchi di protocollo scelti, attacchi di riflessione, ... fatti abituare a queste cose e prova a trovare attacchi contro il tuo protocollo. Rende divertente e imparerai molto.

    
risposta data 14.03.2016 - 18:34
fonte
4

La tua soluzione potrebbe essere influenzata dai seguenti concetti:

Crittografia fai-da-te

La crittografia fai-da-te è un anti-modello di progettazione sicura del software. La maggior parte dei tentativi (> 99%) falliranno. Tuttavia rispetto il tuo tentativo! :-) Ad esempio: non rivelare "passwordSalt", se non è necessario. Aiuta l'aggressore a risolvere la sfida. Dopo una richiesta, un attaccante conosce il sale e ha una sfida che potrebbe essere violata. La sicurezza si basa solo su una password complessa. L'utente malintenzionato può crackare la password offline. Questo non dovrebbe essere il caso per i servizi online. Lo considero altamente insicuro.

Perfect Forward Secrecy

La chiave per la crittografia (token generato dal server) deve essere calcolata su entrambi i lati (client e server) utilizzando Diffie-Hellman Key Exchange o simile. Se qualcuno ha registrato il traffico e ottiene la password dell'utente, è in grado di decodificare il token e quindi decrittografare l'intero traffico, in seguito.

I passaggi 13-16 non sono necessari

Se il client può decifrare "passwordSalt + encryptAes (token, passwordHash)" correttamente, il server deve conoscere "passwordHash", quindi la password dell'utente.

Questo elenco non è completo, in quanto potrebbero essere presenti diversi altri punti deboli.

    
risposta data 14.03.2016 - 17:13
fonte
1

Il tuo tentativo di ricreare una ruota e, a meno che il tuo background non sia in crittografia, è anche probabile che non sia un grande come il tuo intento.

Il tuo obiettivo è inviare dati crittografati da un server a un client con la limitazione che una PKI non può ancora esistere. Il corto è che siamo limitati a Symmetric Key, giusto?

Sono due approcci approssimativi che puoi prendere in considerazione:

Chiave pre-condivisa:

Le chiavi pre-condivise sono generate e impostate nel client e nel server e utilizzate come chiave comune per la crittografia e decrittazione. La tua crittografia dei dati può essere protetta abbastanza bene in questo modo, ma ti occupi della manutenzione di un PSK.

Funzione di derivazione chiave: * Le funzioni di derivazione chiave funzionano sotto un principio simile a quello di PSK ma vengono generate sul client e sul server all'inizio di una sessione. I dati sono dati condivisi tra i due sistemi per generare un valore segreto che può essere utilizzato per crittografare e decifrare i sistemi pt.

Sia Java che C, C ++ hanno librerie che possono costruire queste funzioni.

    
risposta data 15.03.2016 - 18:37
fonte

Leggi altre domande sui tag