2012-05-10 10 views
69

Attualmente sto memorizzando il nome utente (email) e un hash salato dell'email e della password nella KeyChain iOS. Sto usando la versione ARC trovata here.KeyChain iOS che non recupera i valori dallo sfondo

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil]; 
[wrapper setObject:APP_NAME forKey:(__bridge id)kSecAttrService]; 
[wrapper setObject:email forKey:(__bridge id)kSecAttrAccount]; 
[wrapper setObject:token forKey:(__bridge id)kSecValueData]; 

Questo funziona perfettamente quando è necessario estrarre il token per le chiamate di rete mentre l'app è attiva. Funziona per l'accesso da una partenza pulita, così come tutte le chiamate di rete in tutto. Il problema inizia quando l'app è in background.

Ricordare che ciò accade solo sporadicamente e non è ancora necessario collegarlo a una specifica versione o dispositivo iOS.

L'utente scatta una posizione (monitoraggio della regione) e voglio aggiornare il server con il loro stato. Cerco di estrarre il token dal portachiavi, nello stesso modo in cui lo faccio per ogni altra chiamata di rete, e aggiornare lo stato. Ma per alcuni utenti, il valore è nullo. Senza di esso, non posso aggiornare la roba di rete. Perché questo dovrebbe funzionare per la maggior parte, ma non per una piccola percentuale?

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil]; 
NSString *token = [wrapper objectForKey:(__bridge id)kSecValueData]; 

sono tornato alla versione non-ARC del keychainwrapper, ma ho ancora ottenere gli stessi risultati. Apprezzerei qualsiasi feedback su questo. È solo una piccola parte dei miei utenti, ma è un problema che vorrei risolvere e non preoccuparmi. Grazie in anticipo.

Inoltre, tutto il mio lavoro in background è impostato in backgroundTask per impedire che le cose vadano fuori tempo. Non ho alcun problema con il lavoro che circonda il portachiavi, ma non lascio andare avanti finché il mio token non è pieno.

EDIT Ho scoperto il mio problema con il portachiavi che non recuperava i valori dallo sfondo. Pubblicherò la risposta qui sotto e la accetterò poiché ritengo che questa domanda possa diventare preziosa per gli altri in seguito.

risposta

93

La mia domanda era vicina al marchio per il motivo, ma non del tutto. Dopo aver letto blog dopo blog, tutorial dopo tutorial, ne ho trovato uno che ha dato un suggerimento su cosa potrebbe accadere.

Schermate iniziali bloccate. Le esercitazioni del portachiavi lasciavano sempre vuote le impostazioni di accessibilità per il portachiavi, pertanto venivano impostate automaticamente sul livello di accesso più basso/più sicuro di Apple. Questo livello tuttavia non consente l'accesso con portachiavi se l'utente ha un passcode sulla schermata di blocco. Bingo! Questo spiega il comportamento sporadico e il motivo per cui ciò accade solo a una piccola percentuale di utenti.

Una riga di codice, risolve l'intero pasticcio.

[wrapper setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(__bridge id)kSecAttrAccessible]; 

Aggiungere questa riga dove sto impostando i valori di nome utente e password. Funziona come un fascino. Spero che questo aiuti qualcuno là fuori. Mi ha confuso per un bel po 'fino a quando sono stato in grado di mettere insieme i pezzi.

+1

Grazie! Questo è stato molto utile. –

+0

Contento di aver potuto aiutare. Mi ha lasciato perplesso per molto tempo. –

+1

Grazie mille per aver condiviso questo! – pxlshpr

43

Utilizzare kSecAttrAccessibleAfterFirstUnlock anziché kSecAttrAccessibleAlways.


Da Apple's documentation:

kSecAttrAccessibleAfterFirstUnlock
The data in the keychain item cannot be accessed after a restart until the device has been unlocked once by the user.

After the first unlock, the data remains accessible until the next restart. This is recommended for items that need to be accessed by background applications. Items with this attribute migrate to a new device when using encrypted backups.

+3

Questa risposta dovrebbe essere un commento ... – Frizlab

0

Nel mio caso, watchOS2 accede ai dati portachiavi sul lato iOS.

All'inizio, kSecAttrAccessibleWhenUnlockedThisDeviceOnly viene utilizzato. Posso leggere i dati indipendentemente dal fatto che iPhone sia bloccato o meno. E 'molto confusa per me che riceverò errore quando orologio sta tentando di accedere al portachiavi: : SecTrustEvaluate [foglia IssuerCommonName SubjectCommonName]

E alcuni casi essa diventerà: : Errore SecOSStatusWith: [- 25308] Dominio Errore = NSOSStatusErrorDomain Code = -25308 "ks_crypt: e00002e2 non riuscito all'elemento 'oe' (classe 6, bag: 0) Accesso all'elemento tentato mentre il portachiavi è bloccato." UserInfo = {NSDescription = ks_crypt: e00002e2 non è riuscito a 'oe' oggetto (classe 6, il sacchetto: 0). L'accesso alla voce tentata mentre portachiavi è bloccato}

Voglio aggiornare la mia risposta se mi maggiori informazioni.

Problemi correlati