2010-03-23 10 views
5

La mia preoccupazione è che le chiavi e i segreti crittografici gestiti dal garbage collector possano essere copiati e spostati nella memoria senza azzeramento.Come posso garantire che un oggetto Java (contenente materiale crittografico) venga azzerato?

come una possibile soluzione, è sufficiente:

public class Key { 
    private char[] key; 
    // ... 
    protected void finalize() throws Throwable { 
    try { 
     for(int k = 0; k < key.length; k++) { 
     key[k] = '\0'; 
     } 
    } catch (Exception e) { 
     //... 
    } finally { 
     super.finalize(); 
    } 
    } 
    // ... 
} 

EDIT: Si prega di notare che il mio problema è per quanto riguarda non solo zeroization della copia ufficiale (riferimento) dell'oggetto, ma anche tutte le copie stantii le il garbage collector può averlo fatto mentre mescola la memoria in giro per lo spazio e velocizza l'efficienza.

L'esempio più semplice è il GC mark-and-sweep, in cui gli oggetti sono contrassegnati come "referenziati" e quindi tutti gli oggetti vengono copiati in un'altra regione. Il resto sono quindi spazzatura e quindi vengono raccolti. Quando la copia avviene, ciò potrebbe lasciare dati chiave residui che non vengono più gestiti dal garbage collector (perché i dati "ufficiali" si trovano nella nuova regione).

Un banco di prova per questo sarebbe se si utilizza una chiave nel modulo di crittografia, azzerare la chiave, quindi ispezionare l'intero spazio del processo JVM, si dovrebbe non trovare quella chiave.

+0

Mi sono guardato intorno, ma non ho trovato un modo per accedere ai dati del GC. Risponderei che rimuovendo il riferimento tra l'attributo e il suo valore, non c'è modo di accedervi di nuovo, ma non sono sicuro, come hai avuto questo dubbio. – marionmaiden

+0

Non c'è praticamente alcun modo (al momento) di fare ciò che vuoi con gli oggetti java standard. – james

+0

Non sono proprio sicuro di quale sia il punto. L'informazione è in memoria _somewhere_.se un utente malintenzionato ha accesso alla memoria locale, allora sei praticamente bloccato. – james

risposta

0

Quindi sono giunto alla conclusione, da @jambjo e @james, che non c'è davvero nulla che possa fare per impedire che le chiavi vengano copiate e diventate inspiegabili.

La migliore strategia, come sviluppatore, sarebbe quella di rilasciare la libreria di crittografia in C (o qualsiasi altra lingua non gestita) e implementare le proprie risorse lì.

Sarei più che disposto ad accettare una risposta da qualcun altro se riuscissero a trovare una soluzione migliore.

4

Il Java Cryptography Extension Reference Guide consiglia di utilizzare sempre matrici di caratteri anziché stringhe per password in modo che possano essere azzerate in seguito. Forniscono anche un esempio di codice di how you could implement it.

+0

Questo è un ottimo punto , ma non sono sicuro che sia abbastanza. Per favore, guardami l'ultimo aggiornamento alla domanda. –

+0

La sovrascrittura del contenuto di un array non è sufficiente con le nuove VM Java, poiché l'array può essere spostato all'interno dello spazio di memoria del processo, ad es. se l'heap è deframmentato. – jarnbjo

1

La soluzione migliore è utilizzare allocateDirect in NIO. Su un'implementazione sana, non dovrebbe essere spostato. Ma probabilmente sarà idoneo per il paging su disco (si potrebbe sondarlo, immagino) e ibernazione.

1

Quindi cosa se i dati in memoria non vengono sovrascritti in un momento specifico? Se devi preoccuparti di un utente malintenzionato che legge la memoria della tua macchina, è il problema, non quello che è riuscito a trovare lì a che ora.

Quale scenario di attacco effettivo sei preoccupato per le chiavi lasciate in qualche luogo nella memoria di una JVM potrebbe essere un problema serio? Se un attaccante può guardare la memoria della JVM, può anche prendere quelle chiavi mentre le stai ancora usando.

E se sei preoccupato per un utente malintenzionato in esecuzione come utente normale sul sistema che si impadronisce della memoria scartata dalla JVM: AFAIK tutti i sistemi operativi moderni sovrascrivono la memoria allocata di recente con gli zeri.

+0

In primo luogo, l'idea è semplicemente la mitigazione del rischio. Minore è il tempo in cui hai la chiave in memoria, minori sono le probabilità che debba essere vista da un utente malintenzionato. Tuttavia, sì, sei assolutamente corretto. Questo problema che ho è abbastanza artificioso. I requisiti FIPS 140-2 derivano dai requisiti hardware, dove si presume che _everyone_ abbia accesso all'hardware, quindi si desidera ridurre la finestra di attacco. Per un modulo software, questo non ha molto senso. –

Problemi correlati