implicações de segurança de armazenar uma senha em Settings.bundle e ficando com CFPreferencesCopyAppValue

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

Pergunta

Desculpas para a obviedade aparente desta questão, mas por alguma razão eu não tenho sido capaz de encontrar uma resposta definitiva na documentação da Apple sobre onde e como Settings.bundle informações senha é armazenada. A minha pergunta: se eu precisar armazenar algumas credenciais para um aplicativo, e eu uso um Settings.bundle para que a senha é digitada em um campo de texto PSTextFieldSpecifier na área Configurações da Apple com IsSecure = YES, e então eu acessar o valor do meu aplicativo usando CFPreferencesCopyAppValue, não escrevê-lo para fora para NSUserDefaults e enviá-lo somente sobre a rede de forma segura, o quão seguro é que o armazenamento e método de recuperação quando comparado a armazenar e recuperar a senha usando o chaveiro em minhas próprias configurações de aplicativos? Obrigado pela sua entrada.

Foi útil?

Solução

CFPreferencesCopyAppValue é apenas a maneira Núcleo Fundação de acessar a mesma informação que você começa quando usando NSUserDefaults. Em termos de segurança, as características são exatamente os mesmos. Ou seja, ele não está criptografado. É seguro apenas no sentido de que ele é obscurecida. A resposta "correta" é usar o chaveiro.

O contador para isso é que muitos aplicativos usam NSUserDefaults para armazenar senhas. Você poderia argumentar que a menos que os controles de senha de acesso à informação de qualquer valor, então não vale a pena o esforço em tentar usar o chaveiro. O que me traz ao segundo argumento em favor do uso de um campo seguro na aplicação Definições:. A API chaveiro é hediondo e, na minha experiência, pelo menos, escrever código livre de erros é complicado

Outras dicas

Não guarde a senha do usuário nas configurações do bundle.
Não é seguro.

Lembre-se, você não precisa saber o que a senha original é, você precisa saber se a senha que o usuário digita jogos a senha original. A maneira correta de lidar com senhas em iOS, quer seja para

  • Use o keychain, como outros já referiram
  • Gerar uma função hash unidireccional criptográfica usando SHA-512 ou outro criptografia e armazenar o hash resultante e sal em NSUserDefaults

Destas opções, criptografar a senha e armazenar o hash + sal é de longe o mais fácil. Aqui está o que você faz para armazenar a senha:

  1. Grab a senha do usuário
  2. Crie um valor salt aleatório
  3. Criar um forward-only de hash usando SHA-512 e o valor salt aleatório
  4. Armazenar o hash resultante eo valor sal em NSUserDefaults -. Estes valores não podem ser usados ??por hackers para determinar a senha original, por isso não há necessidade de armazená-los em um lugar seguro

Agora, quando o usuário digita sua senha e você tem que verificar se ele está correto, aqui está o que você faz:

  1. Grab a senha do usuário
  2. Grab o valor de hash sal + salvo anteriormente a partir NSUserDefaults
  3. Criar um forward-only de hash usando a mesma função hash one-way que você usou para criptografar a senha original - passá-lo a tentativa de senha e o valor sal NSUserDefaults
  4. Compare o hash resultante com o que foi armazenado em NSUSerDefaults. Se eles são o mesmo, então o usuário digitou a senha correta.

Aqui está o código para gerar o sal eo forward-only de hash:

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];
}

código para este exemplo foi encontrada aqui: http://blog.securemacprogramming.com/2011/04/storing-and-testing-credentials-cocoa-touch-edition/

Keychain no iPhone vai ser o mais seguro, a menos que você estiver usando criptografia de costume, o que é muito difícil de fazer (e exportação). NSUserDefaults não é considerado seguro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top