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

StackOverflow https://stackoverflow.com/questions/1248575

Вопрос

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

Это было полезно?

Решение

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

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

Другие советы

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

Помните, вам не нужно знать исходный пароль, вам нужно знать, вводит ли пароль, который вводит пользователь. Матчи оригинальный пароль.Правильный способ обращения с паролями в 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/

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top