2010-03-02 15 views
6

Tengo algunos datos confidenciales que deseo borrar directamente después del uso. Actualmente, los datos confidenciales tienen la forma de NSString. NSString es, en mi entender, inmutable, lo que significa que no puedo borrar los datos. NSMutableString parece más apropiado, sin embargo, ya que es mutable y tiene métodos como replaceCharactersInRange y deleteCharactersInRange. No tengo conocimiento de los detalles de la implementación, entonces me pregunto si NSMutableString me serviría.Datos confidenciales: NSString VS NSMutableString (iPhone)

Respuesta

3

Me temo que NSMutableString trataría de optimizar y dejar la cadena en la memoria. Si desea más control intente asignar su propia memoria y luego cree un NSString con ella. Si lo hace, puede sobrescribir la memoria antes de liberarla.

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

¡Gracias, esto era exactamente lo que estaba pidiendo! – AOO

+1

'NSString' puede crear copias adicionales del buffer pasado para sus propios fines. Ejemplo: al llamar '- [NSString UTF8String]' se creará una copia interna adicional que se liberará pero no se borrará cuando lo haga 'NSString'. Si quiere que se garantice que los datos confidenciales se limpian, * NO * use 'NSString'. – rpetrich

1

Usted necesita para limpiar el puntero c con ceros con una función memset sin embargo una llamada memset puede ser optimizado por el compilador, consulte What is the correct way to clear sensitive data from memory in iOS?

Así que el código podría ser algo como esto:

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

Pero tenga cuidado al borrar el puntero c subyacente de un NSString. En un dispositivo, por ejemplo, si la cadena contiene la palabra "contraseña", el puntero c subyacente solo reutiliza o apunta a la misma dirección que usa el sistema y se bloqueará al intentar borrar esta área de la memoria.

Para estar seguro, puede utilizar una matriz de caracteres, no el puntero de char, para almacenar sus cadenas sensibles y borrarlas sin ponerlas nunca en un objeto NSString.

1

Si un atacante puede leer el contenido de la memoria, está más allá de las mangueras.

-release la cadena y listo. No hay forma de saber si ha eliminado las posibles copias de la cadena en varias memorias caché (como si la dibujara en la pantalla, etc.).

Probablemente tenga problemas de seguridad mucho más importantes de los que preocuparse.

0

A partir de iOS9, el puntero interno de NSString obtenido del fragmento debajo de se ha convertido en de solo lectura y genera un acceso incorrecto al intentar establecer los bytes.

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

Es posible con NSMutableString pero si usted tiene otra fuente NSString, digamos de un campo de texto, que seguirá siendo fuente en la memoria y que está todavía fuera de suerte.

Si está creando un NSString nuevo, la mejor manera es implementar su propia clase String con el conjunto de bytes subyacente. Proporcione un método para crear copias NSString utilizando el conjunto de bytes subyacente como el puntero 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); 
} 
Cuestiones relacionadas