2009-08-08 16 views
10

Ci scusiamo per l'apparente ovvietà di questa domanda, ma per qualche ragione non sono stato in grado di trovare una risposta definitiva nella documentazione di Apple su dove e come Impostazioni .bundle password info è memorizzata. La mia domanda: se ho bisogno di memorizzare alcune credenziali per un'app, e uso un Settings.bundle in modo che la password venga inserita in un campo di testo PSTextFieldSpecifier nell'area Impostazioni di Apple con IsSecure = YES, e quindi accedo al valore dalla mia app usando CFPreferencesCopyAppValue, non scrivendo mai su NSUserDefaults e inviandolo solo attraverso la rete in modo sicuro, quanto è sicuro il metodo di archiviazione e recupero rispetto all'archiviazione e al recupero della password utilizzando il portachiavi nelle impostazioni della mia app? Grazie per il tuo contributo.Implicazioni sulla sicurezza di memorizzare una password in Settings.bundle e ottenere con CFPreferencesCopyAppValue

+0

consideri memorizzare l'hash invece della password. Vedi la mia risposta qui sotto. – memmons

+0

Grazie per il buon suggerimento - come ho detto al momento in cui ho chiesto questo un paio di anni fa, ho solo bloccato con l'uso del portachiavi. – Halle

+0

Sì. È una buona opzione e Apple l'ha sicuramente migliorata da quando hai chiesto per la prima volta. – memmons

risposta

8

CFPreferencesCopyAppValue è solo il modo principale per accedere alle stesse informazioni ottenute quando si utilizza NSUserDefaults. In termini di sicurezza, le funzionalità sono esattamente le stesse. Cioè, non è crittografato. È sicuro solo nel senso che è oscurato. La risposta "corretta" è usare il portachiavi.

Il contatore è che molte applicazioni utilizzano NSUserDefaults per memorizzare le password. Si potrebbe obiettare che, a meno che la password non controlli l'accesso alle informazioni di qualsiasi valore, non valga la pena tentare di utilizzare il portachiavi. Il che mi porta al secondo argomento a favore dell'utilizzo di un campo sicuro nell'applicazione Settings: l'API keychain è orribile e, almeno nella mia esperienza, scrivere codice senza errori è complicato.

+0

Buono a sapersi, grazie. Continuerò con il portachiavi - non mi è stato chiaro che le informazioni sulle impostazioni finissero nello stesso posto di NSUserDefaults. – Halle

+2

Potresti essere interessato all'uso di SFHFKeychainUtils: http://github.com/ldandersen/scifihifi-iphone/tree/d4298f123a06a91acbe8422ddb6164be3dbcff9e/security. Lo sto usando per memorizzare le password e semplifica davvero l'uso del portachiavi. –

+1

Ho trovato che il codice di esempio di Apple che ha un'implementazione di un wrapper portachiavi per Keychain Services è piuttosto facile da seguire (e quindi utilizzare successivamente il wrapper per la gestione del portachiavi dell'app) se estrai il codice di presentazione dalla vista controller, che penso sia dove gran parte della confusione arriva con quell'esempio. – Halle

3

Il portachiavi su iPhone sarà il più sicuro, a meno che non si stia utilizzando la crittografia personalizzata, operazione molto difficile da eseguire (ed esportazione). NSUserDefaults non è considerato sicuro.

8

Non salvare la password di un utente nel pacchetto di impostazioni.
Non è sicuro.

Ricordare che non è necessario conoscere la password originale, è necessario sapere se la password immessa dall'utente corrisponde alla password originale. Il modo corretto di affrontare le password in iOS è a uno

  • Utilizzare il portachiavi, come altri hanno detto
  • generare una funzione hash unidirezionale crittografico utilizzando SHA-512 o altri crittografia e memorizzare l'hash risultante e sale in NSUserDefaults

di queste opzioni, la crittografia della password e memorizzare l'hash + sale è di gran lunga il più facile. Ecco cosa fare per memorizzare la password:

  1. Grab la password da parte dell'utente
  2. Creare un valore salt casuale
  3. Creare un forward-only hash utilizzando SHA-512 e il valore sale a caso
  4. Memorizza l'hash risultante e il valore di sale in NSUserDefaults - questi valori non possono essere utilizzati dagli hacker per determinare la password originale, quindi non è necessario memorizzarli in un luogo sicuro.

Ora, quando l'utente immette la propria password e si deve verificare se è corretto, ecco cosa dovete fare:

  1. Grab la password da parte dell'utente
  2. Afferra l'hash precedentemente salvato + sale valore da NSUserDefaults
  3. Creare un hash forward-only con la stessa funzione di hash a senso unico che si è utilizzato per crittografare la password originale - passandogli il tentativo di password e il valore sale dalla NSUserDefaults
  4. Confrontare l'hash risultante con quello che è stato memorizzato in NSUSerDefaults. Se sono uguali, l'utente ha inserito la password corretta.

Ecco il codice per generare il sale e l'hash forward-only:

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

codice per questo esempio è stato trovato qui: http://blog.securemacprogramming.com/2011/04/storing-and-testing-credentials-cocoa-touch-edition/

Problemi correlati