2009-03-14 2 views
6

Le nostre applicazioni basate sul web hanno account utente legati agli utenti con le password specificate durante la creazione dell'account. Nel caso di Java, come si processa la password in modo sicuro, prima di persistere nel suo hash nel database.In che modo una password di archivio si blocca in modo sicuro nella memoria, quando si creano gli account?

Per essere più specifici, come si fa a garantire che la stringa contenente la password venga raccolta in un intervallo di tempo sufficientemente breve?

+0

Questo potrebbe essere utile per proteggere la password durante il processo di registrazione.http: //wheelersoftware.com/articles/spring-security-hash-salt-passwords.html –

risposta

6

Se si ha la possibilità (potrebbe essere difficile nelle applicazioni Web), sarebbe meglio memorizzare le password negli array di caratteri piuttosto che memorizzarle in stringhe. Se avete finito la memorizzazione della password è possibile sovrascrivere in memoria utilizzando Array.fill() e rendere il riferimento disponibile per il garbage collector scartando esso:

Arrays.fill(password, ' '); 
password = null; 

Ho appena notato che l'azzeramento del la password sarebbe un po 'paranoico, ma è possibile fare se rassicura voi :)

+0

Se ciò è possibile in un'app Web, leggere la password dal flusso di input del servlet in un array di byte e quindi riempire l'array di zeri dopo aver mantenuto la password, quindi dovrebbe risultare un approccio praticabile. Il progetto Java OWASP lo utilizza in un esempio, ma non per le password persistenti. –

+2

Questo non richiede che il garbage collector non compatta lo stack e quindi lasci una copia dell'array altrove nella memoria? –

+1

@KeeperOfTheSoul: Sì, alla fine dipende dal comportamento del GC. Dipende anche dal fatto che la matrice verrà serializzata o meno. Tutto sommato, desideravo che Java avesse una classe SecureString simile a quella di Microsoft .Net. –

4

Se si crea l'hash sul lato client, non è necessario pensare a questo problema. La semplice password non viene mai inviata al server.

+0

Sì, questo è un buon approccio, ma non lascerebbe anche quello attaccanti con la capacità di studiare l'algoritmo hash in uso? Garantito che è la sicurezza attraverso l'oscurità in un modo, ma limita la quantità di informazioni disponibili per l'attaccante su come vengono memorizzate le password. –

+0

Questa sarebbe un'opzione ma non è possibile che un utente malintenzionato intercetti l'hash generato dal client e quindi genera nuovamente la stessa richiesta HTTP per accedere? –

+0

@Markus, HTTPS viene sempre utilizzato, quindi la probabilità di un attacco MITM è bassa o nullo. –

2

Due parole: ambito locale. Le variabili dichiarate per l'elaborazione della password devono avere l'ambito più piccolo possibile.

Una volta che le variabili escono dall'ambito, gli oggetti sono idonei per la garbage collection.

Spesso, stai raccogliendo le cose da una richiesta. Vuoi una transazione molto, molto piccola che accetta la richiesta, la password hash, lo persiste e reindirizza. La pagina verso cui si effettua il reindirizzamento può quindi recuperare il contenuto ed eseguire tutta l'elaborazione "altra" che fa parte dell'applicazione.

1

Non esiste alcun modo per garantire che le password di testo in chiaro vengano rimosse dalla memoria in Java.

Tuttavia un hacker non ha bisogno di accedere alla memoria di un programma per ottenere password di testo chiare. Ci sono modi molto più semplici (come ad esempio sniffare i pacchetti), quindi è altamente improbabile che qualcuno possa fare affidamento su questo approccio.

L'approccio migliore è far crittografare il client come @ suggerisce Mork0075. Tuttavia, mentre ciò significa che non è possibile ottenere facilmente la password, un programma può comunque ottenere la versione crittografata delle password e fingere così di essere un utente. Un modo per aggirare questo è crittografare l'intera connessione usando SSL.

Tutto questo è piuttosto accademico, poiché l'approccio più semplice per un hacker è quello di monitorare i pacchetti nel database e ottenere la password per il database. Sospetto che l'accesso diretto al tuo database sia più pertinente ... o forse non lo è. ;)

+0

Sto cercando di proteggere le password, non perché un utente malintenzionato potrebbe tentare questo approccio - la scatola è stata compromessa se è in grado di sbirciare nella memoria, quindi ci sono cose più grandi di cui preoccuparsi. Sto cercando di impedire che le password vengano visualizzate in un dump dell'heap Java ottenuto per la diagnosi. –

0

Utilizzare una sfida password

  1. Server sceglie un valore sfida e lo invia al Cliente
  2. Il server esegue una traduzione a 1 via con la password e la sfida, ad es. MD5(CONCAT(challenge, password)) e lo assegna alla sessione.
  3. La password in testo semplice è ora fuori portata e pronta per la garbage collection.
  4. Il client esegue anche la stessa traduzione e invia il risultato al server.
  5. Se Server e Client scelgono lo stesso valore finale, il client viene autenticato.

Questo metodo impedisce attacchi di riproduzione, ma richiede il valore sfida essere molto imprevedibile (casuale) e spesso non riutilizzato (lungo).

La password di testo normale è disponibile solo durante la gestione della richiesta di connessione iniziale, non durante l'autenticazione. Non importa per quanto tempo il risultato della traduzione a 1 via è in ambito (non garbage collection) perché ha un piccolo valore di replay.

+0

Funzionerebbe bene per il processo di login ma l'autore ha richiesto la registrazione di un account, quindi è necessario memorizzare anche un valore hash in un database. Questo hash non può essere generato tramite un valore di sfida poiché non è stato possibile ripristinarlo all'accesso. –

5

Non si utilizza una stringa. Si utilizza un carattere [] e quindi si sovrascrive il carattere [] al termine.

Non ci sono assolutamente garanzie quando si tratta di garbage collection (a parte il fatto che il finalizzatore verrà eseguito prima che l'oggetto venga raccolto). Il GC non può mai essere eseguito, se viene eseguito potrebbe mai GC String che contiene la password.