Sensitive data: NSString VS NSMutableString (iPhone)

ぃ、小莉子 提交于 2019-12-19 07:10:54

问题


I have some sensitive data I want to clear directly after use. Currently, the sensitive data is in the form of NSString. NSString is in my understanding immutable, meaning that I can't really clear the data. NSMutableString seems more appropriate, though, as it is mutable and has methods like replaceCharactersInRange and deleteCharactersInRange. I have no knowledge of the implementation details so I wonder if NSMutableString would serve my purpose?


回答1:


I would be afraid NSMutableString would try to optimize and leave the string in memory. If you want more control try allocating your own memory then create an NSString with it. If you do that you can overwrite the memory before you release it.

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



回答2:


You need to wipe the c pointer with zeros with a memset function however a memset call can be optimized out by the compiler, see What is the correct way to clear sensitive data from memory in iOS?

So the code could be something like this:

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

But be careful clearing the underlying c pointer of an NSString. On a device for example, if the string contains the word "password", the underlying c pointer just reuses or points to the same address as used by the system and you will crash by trying to wipe this area of memory.

To be safe you may want to use a char array, not the char pointer, to store your sensitive strings and wipe them after without ever putting it into an NSString object.




回答3:


If an attacker can read the contents of memory, you are beyond hosed.

-release the string and be done with it. There's no way to know if you've deleted any possible copies of the string in various caches (such as if you draw it to screen, etc).

You probably have much more significant security issues to worry about.




回答4:


As of iOS9, inner pointer of NSString obtained from the snippet below has become read-only and generates bad access when trying to set the bytes.

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

It is possible with NSMutableString but then if you have another NSString source, say from a textfield, that source will still be in memory and you're still out of luck.

If you are creating a new NSString, The best way is implement your own String class with underlying byte array. Provide a method to create NSString copies using the underlying byte array as the inner pointer.:

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


来源:https://stackoverflow.com/questions/2361981/sensitive-data-nsstring-vs-nsmutablestring-iphone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!