2010-03-02 9 views
6

Ho alcuni dati sensibili che desidero cancellare direttamente dopo l'uso. Attualmente, i dati sensibili sono sotto forma di NSString. NSString è a mio avviso immutabile, il che significa che non riesco a cancellare i dati. NSMutableString sembra più appropriato, in quanto è mutabile e ha metodi come replaceCharactersInRange e deleteCharactersInRange. Non ho alcuna conoscenza dei dettagli di implementazione, quindi mi chiedo se NSMutableString potrebbe servire al mio scopo?Dati sensibili: NSString VS NSMutableString (iPhone)

risposta

3

Avrei paura che NSMutableString tentasse di ottimizzare e di lasciare la stringa in memoria. Se vuoi avere più controllo, prova ad allocare la tua memoria, quindi crea una NSString con essa. Se lo fai, puoi sovrascrivere la memoria prima di rilasciarla.

char* block = malloc(200); 
NSString* string = [[NSString alloc] initWithBytesNoCopy:length:encoding:freeWhenDone]; 
//use string 
memset(block, 0, 200);// overwrite block with 0 
[string release]; 
free(block); 
+0

Grazie, questo era esattamente quello che stavo chiedendo! – AOO

+1

'NSString' può creare copie aggiuntive del buffer passato per i propri scopi. Esempio: chiamando '- [NSString UTF8String]' creerà una copia interna aggiuntiva che verrà rilasciata ma non cancellata quando si esegue 'NSString'. Se vuoi essere sicuro che i dati sensibili siano puliti, * NON * usa 'NSString'. – rpetrich

1

È necessario pulire il puntatore c con gli zeri con una funzione memset comunque una chiamata memset può essere ottimizzato dal compilatore, vedere What is the correct way to clear sensitive data from memory in iOS?

Così il codice potrebbe essere qualcosa di simile:

NSString *string = @"hi"; 
unsigned char *stringChars = (unsigned char *)CFStringGetCStringPtr((CFStringRef)string, CFStringGetSystemEncoding()); 
safeMemset(stringChars, 0, [string length]); 

Ma attenzione a cancellare il puntatore c sottostante di una NSString. Su un dispositivo, ad esempio, se la stringa contiene la parola "password", il puntatore c sottostante riutilizza o punta allo stesso indirizzo utilizzato dal sistema e si bloccherà tentando di cancellare quest'area di memoria.

Per sicurezza si consiglia di utilizzare un array di caratteri, non il puntatore del carattere, per memorizzare le stringhe sensibili e pulirle dopo senza mai inserirle in un oggetto NSString.

1

Se un utente malintenzionato è in grado di leggere il contenuto della memoria, si è oltre il getto.

-release la stringa ed essere fatto con esso. Non c'è modo di sapere se hai cancellato qualsiasi possibile copia della stringa in varie cache (come se la disegna sullo schermo, ecc.).

Probabilmente hai problemi di sicurezza molto più importanti di cui preoccuparti.

0

Al iOS9, puntatore interno NSString ottenuti dal frammento di sotto è diventato di sola lettura e genera cattivo accesso quando si cerca di impostare i byte.

unsigned char *stringChars = (unsigned char *)CFStringGetCStringPtr((CFStringRef)string, CFStringGetSystemEncoding()); 

E 'possibile con NSMutableString ma poi se si dispone di un'altra fonte NSString, ad esempio da un campo di testo, quella fonte sarà ancora in memoria e siete ancora fuori di fortuna.

Se si sta creando un nuovo NSString, il modo migliore è implementare la propria classe String con l'array di byte sottostante. Fornire un metodo per creare copie NSString utilizzando l'array di byte sottostante come puntatore interno .:

-(NSString *)string 
{ 
    return [[NSString alloc] initWithBytesNoCopy:_buff length:_length encoding:NSUTF8StringEncoding freeWhenDone:NO]; 
} 

// Will prematurely wipe data and all its copies when called 
- (void)clear 
{ 
    // Volatile keyword disables compiler's optimization 
    volatile unsigned char *t = (unsigned char *)_buff; 
    int len = _length; 
    while (len--) { 
     *t++ = 0; 
    } 
} 

// In case you forget to clear, it will cleared on dealloc 
- (void)dealloc 
{ 
    [self clear]; 
    free(_buff); 
}