Последствия для безопасности хранения пароля в Settings.bundle и получения с помощью CFPreferencesCopyAppValue

Приносим извинения за кажущуюся очевидность этого вопроса, но по какой-то причине я не смог найти в документации Apple однозначного ответа о том, где и как хранится информация о пароле Settings.bundle. Мой вопрос: если мне нужно сохранить некоторые учетные данные для приложения, и я использую Settings.bundle, чтобы пароль вводился в текстовое поле PSTextFieldSpecifier в области настроек Apple с помощью IsSecure = YES, а затем я получаю доступ к значению из своего приложения, используя CFPreferencesCopyAppValue, никогда не записывать его в NSUserDefaults и только безопасно отправлять по сети, насколько безопасен этот метод хранения и извлечения по сравнению с хранением и извлечением пароля с использованием цепочки для ключей в моих собственных настройках приложения? Спасибо за ваш вклад.


person Halle    schedule 08.08.2009    source источник
comment
Рассмотрите возможность сохранения хэша вместо пароля. Смотрите мой ответ ниже.   -  person memmons    schedule 30.08.2011
comment
Спасибо за хорошее предложение - как я уже упоминал, когда задавал этот вопрос пару лет назад, я просто придерживался использования цепочки для ключей.   -  person Halle    schedule 30.08.2011
comment
Ага. Это хороший вариант, и Apple, безусловно, улучшила его с тех пор, как вы впервые спросили.   -  person memmons    schedule 30.08.2011


Ответы (3)


CFPreferencesCopyAppValue — это просто основной способ доступа к той же информации, которую вы получаете при использовании NSUserDefaults. С точки зрения безопасности, функции точно такие же. То есть он не зашифрован. Он безопасен только в том смысле, что скрыт. «Правильный» ответ — использовать брелок.

Обратной стороной этого является то, что многие приложения используют NSUserDefaults для хранения паролей. Вы можете возразить, что если пароль не контролирует доступ к любой информации, то попытки использовать связку ключей не стоят усилий. Это подводит меня ко второму аргументу в пользу использования безопасного поля в приложении «Настройки»: API цепочки для ключей ужасен, и, по крайней мере, по моему опыту, написать безошибочный код сложно.

person Stephen Darlington    schedule 08.08.2009
comment
Полезно знать, спасибо. Я собираюсь придерживаться цепочки для ключей — мне не было ясно, что информация о настройках оказывается в том же месте, что и NSUserDefaults. - person Halle; 08.08.2009
comment
Вам может быть интересно использовать SFHFKeychainUtils: github.com/ldandersen/scifihifi-iphone/ дерево/. Я использую его для хранения паролей, и это действительно упрощает использование цепочки для ключей. - person Chu Yeow; 14.08.2009
comment
Я обнаружил, что образец кода Apple, который имеет реализацию оболочки цепочки для ключей для служб цепочки ключей, довольно легко следовать (и затем использовать оболочку для управления цепочкой ключей вашего собственного приложения), если вы удаляете код представления из контроллера представления , и я думаю, что в этом примере возникает большая часть путаницы. - person Halle; 20.02.2010

Не сохраняйте пароль пользователя в пакете настроек.
Это небезопасно.

Помните, что вам не нужно знать исходный пароль, вам нужно знать, соответствует ли пароль, который вводит пользователь, исходному паролю. Правильный способ работы с паролями в iOS — либо

  • Используйте брелок, как уже упоминали другие
  • Создайте криптографическую одностороннюю хеш-функцию, используя SHA-512 или другое шифрование, и сохраните полученный хэш и соль в NSUserDefaults.

Из этих вариантов шифрование пароля и сохранение хэша + соли на сегодняшний день является самым простым. Вот что вы делаете, чтобы сохранить пароль:

  1. Забрать пароль у пользователя
  2. Создать случайное значение соли
  3. Создайте прямой хеш, используя SHA-512 и случайное значение соли
  4. Сохраните полученный хэш и значение соли в NSUserDefaults — эти значения не могут быть использованы хакерами для определения исходного пароля, поэтому нет необходимости хранить их в безопасном месте.

Теперь, когда пользователь вводит свой пароль и вам нужно проверить его правильность, вот что вы делаете:

  1. Забрать пароль у пользователя
  2. Возьмите ранее сохраненный хэш + значение соли из NSUserDefaults
  3. Создайте прямой хэш, используя ту же одностороннюю хеш-функцию, которую вы использовали для шифрования исходного пароля, передав ей пароль и значение соли из NSUserDefaults.
  4. Сравните полученный хэш с тем, что был сохранен в NSUSerDefaults. Если они совпадают, то пользователь ввел правильный пароль.

Вот код для генерации соли и прямого хэша:

NSString *FZARandomSalt(void) {
    uint8_t bytes[16] = {0};
    int status = SecRandomCopyBytes(kSecRandomDefault, 16, bytes);
    if (status == -1) {
        NSLog(@"Error using randomization services: %s", strerror(errno));
        return nil;
    }
    NSString *salt = [NSString stringWithFormat: @"%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
                      bytes[0],  bytes[1],  bytes[2],  bytes[3],
                      bytes[4],  bytes[5],  bytes[6],  bytes[7],
                      bytes[8],  bytes[9],  bytes[10], bytes[11],
                      bytes[12], bytes[13], bytes[14], bytes[15]];
    return salt;
}

NSData *FZAHashPassword(NSString *password, NSString *salt) {
    NSCParameterAssert([salt length] >= 32);
    uint8_t hashBuffer[64] = {0};
    NSString *saltedPassword = [[salt substringToIndex: 32] stringByAppendingString: password];
    const char *passwordBytes = [saltedPassword cStringUsingEncoding: NSUTF8StringEncoding];
    NSUInteger length = [saltedPassword lengthOfBytesUsingEncoding: NSUTF8StringEncoding];
    CC_SHA512(passwordBytes, length, hashBuffer);
    for (NSInteger i = 0; i < 4999; i++) {
        CC_SHA512(hashBuffer, 64, hashBuffer);
    }
    return [NSData dataWithBytes: hashBuffer length: 64];
}

Код для этого примера можно найти здесь: http://blog.securemacprogramming.com/2011/04/storing-and-testing-credentials-cocoa-touch-edition/

person memmons    schedule 30.08.2011

Связка ключей на iPhone будет наиболее безопасной, если только вы не используете специальное шифрование, которое очень сложно сделать (и экспортировать). NSUserDefaults не считается безопасным.

person Jordan    schedule 08.08.2009