У меня есть некоторые конфиденциальные данные, которые я хочу очистить сразу после использования. В настоящее время конфиденциальные данные находятся в форме NSString. NSString в моем понимании неизменен, что означает, что я не могу действительно очистить данные. NSMutableString кажется более подходящим, хотя, поскольку он изменен и имеет методы, такие как replaceCharactersInRange и deleteCharactersInRange. Я не знаю деталей реализации, поэтому я задаюсь вопросом, будет ли NSMutableString служить моей цели?Чувствительные данные: NSString VS NSMutableString (iPhone)
ответ
Я боялся, что NSMutableString попытается оптимизировать и оставить строку в памяти. Если вы хотите больше контроля, попробуйте выделить свою собственную память, а затем создайте с ней 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 однако вызов MemSet может быть оптимизирована путем компилятором см What is the correct way to clear sensitive data from memory in iOS?
Так что код может быть что-то вроде этого:
NSString *string = @"hi";
unsigned char *stringChars = (unsigned char *)CFStringGetCStringPtr((CFStringRef)string, CFStringGetSystemEncoding());
safeMemset(stringChars, 0, [string length]);
Но будьте осторожны, очищая основной указатель c NSString. Например, на устройстве, если строка содержит слово «пароль», базовый c-указатель просто повторяет или указывает на тот же адрес, который используется системой, и вы потерпите крах, пытаясь стереть эту область памяти.
Чтобы быть в безопасности, вы можете использовать массив символов, а не указатель символов, чтобы хранить ваши чувствительные строки и уничтожить их после того, как они не будут помещены в объект NSString.
Если злоумышленник может читать содержимое памяти, вы находитесь за пределами hosed.
-release
Строка и сделайте с ней. Невозможно узнать, удалили ли вы какие-либо возможные копии строки в разных кешах (например, если вы нарисуете ее на экране и т. Д.).
У вас, вероятно, есть гораздо более серьезные проблемы с безопасностью, о которых нужно беспокоиться.
Начиная с iOS9, внутренний указатель NSString, полученный из фрагмента ниже , стал доступен только для чтения и создает плохой доступ при попытке установить байты.
unsigned char *stringChars = (unsigned char *)CFStringGetCStringPtr((CFStringRef)string, CFStringGetSystemEncoding());
Можно с NSMutableString но если у вас есть еще один источник NSString, скажем, от текстового поля, что источник будет по-прежнему находиться в памяти, и вы до сих пор не повезло.
Если вы создаете новую NSString, лучший способ - реализовать собственный класс String с базовым массивом байтов. Предоставьте метод создания копий 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);
}
Спасибо, это именно то, о чем я просил! – AOO
'NSString' может создавать дополнительные копии буфера, переданного для собственных целей. Пример: вызов '- [NSString UTF8String]' создаст дополнительную внутреннюю копию, которая будет выпущена, но не будет удалена, когда будет выполняться 'NSString'. Если вы хотите гарантировать, что конфиденциальные данные будут очищены, сделайте * NOT * использовать 'NSString'. – rpetrich