Se si sta codificando, molte lingue "non gestite" supportano (richiedono) la possibilità di eliminare la memoria allocata dinamicamente. Se vuoi essere veramente sicuro, di solito puoi anche impostare il valore di detta memoria su tutti gli zeri, o su qualcosa che non è utile per un utente malintenzionato (dati casuali, "Tutto lavoro e niente gioco ...", ecc.)
Nei runtime della memoria gestita come JVM o CLR, non hai questo controllo; il garbage collector controlla se il codice in esecuzione ha ancora riferimenti all'oggetto e, in caso contrario, lo pianifica per la raccolta. Il processo di marcatura e la risultante liberazione della memoria e la riorganizzazione dell'heap si verificano quando il runtime pensa che potrebbe essere un buon momento per ripulire, non quando si sa che qualcosa dovrebbe essere ripulito. In questi ambienti, di solito c'è una struttura fornita appositamente per gestire i dati sensibili.
In .NET, il tipo principale per queste cose è chiamato SecureString e ha diversi vantaggi rispetto al System.String di base:
- SecureString è mutabile, diversamente da String che, sebbene sia un tipo di riferimento, è considerato immutabile; ogni volta che viene assegnata una variabile stringa, viene creato un nuovo oggetto String nell'heap, il che significa che quando si lavora con dati sensibili, molte copie dfferenti di tali dati possono esistere nello heap contemporaneamente. SecureString gestisce tutte le manipolazioni di se stesso all'interno di un singolo spazio di memoria nell'heap.
- I dati conservati in SecureString vengono crittografati in ogni momento, quindi anche se viene lasciato in giro, l'utente malintenzionato dovrebbe anche accedere al contenitore di chiavi memorizzato nella memoria non gestita protetta.
-
L'oggetto è derivato da una famiglia di classi base che lo identifica come "finalizzatore critico"; fino a quando il CLR ha voce in capitolo, il finalizzatore, che nel caso di SecureString rimuove tutti i dati sensibili dalla memoria, sarà eseguito quando l'oggetto esce dall'ambito.
-
L'utente può cancellare in modo sincrono lo stato dei dati di SecureString chiamando Clear (). Questo accade anche se l'utente utilizza l'interfaccia incorporata IDisposable, o se non viene ripulito dall'utente, quando l'oggetto è finalizzato dal garbage collector, ma l'utente è incoraggiato a usare Clear () o Dispose () per ripulire memoria esattamente nel momento in cui l'utente è sicuro che non ne avrà più bisogno.
In tutti i casi, i dati sensibili devono essere conservati come testo normale nella memoria per il minimo tempo possibile prima della rimozione. Se può essere mantenuto crittografato per la maggior parte del tempo, e solo decrittografato in testo normale quando necessario (come consente SecureString), è grandioso.