敏感数据:NSString VS NSMutableString(iPhone)

我有一些敏感数据,我想在使用后直接清除。 目前,敏感数据是以NSString的forms出现的。 NSString在我的理解是不可变的,这意味着我不能真正清除数据。 NSMutableString似乎更合适,虽然它是可变的,并有像replaceCharactersInRange和deleteCharactersInRange方法。 我不知道实现的细节,所以我不知道是否NSMutableString将服务于我的目的?

我会害怕NSMutableString会尝试优化和留在内存中的string。 如果你想更多的控制尝试分配你自己的内存然后创build一个NSString。 如果你这样做,你可以在释放之前覆盖内存。

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); 

您需要使用memset函数清零c指针,但memset调用可以通过编译器进行优化,请参阅在iOS中清除内存中敏感数据的正确方法是什么?

所以代码可能是这样的:

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

但要小心清除NSString的底层c指针。 例如,在一个设备上,如果string包含单词“password”,则底层的c指针只是重用或指向系统所使用的相同地址,您将通过尝试擦除这个区域的内存来崩溃。

为了安全起见,您可能需要使用char数组而不是char指针来存储敏感string,然后将其擦除,而不必将其放入NSString对象中。

如果攻击者可以读取内存的内容,那么你已经不在乎了。

-releasestring,并完成它。 没有办法知道你是否已经删除了各种caching中的任何可能的string副本(例如,如果你把它画到屏幕上等)。

你可能有更重要的安全问题需要担心。

从iOS9开始,从下面的代码片段获得的NSString的内部指针已经变为只读,并且在尝试设置字节时会产生错误的访问

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

这可能与NSMutableString,但如果你有另一个NSString源,从文本字段说,该源将仍然在内存中,你仍然运气不好。

如果你正在创build一个新的NSString,最好的方法是用底层字节数组实现你自己的String类。 提供一种方法来创build使用底层字节数组作为内部指针的NSString副本。

 -(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); }