2013-12-14 62 views
3

對於我的應用程序,我必須以安全的方式存儲用戶名/密碼,並認爲它是存儲在系統鑰匙串中的最佳解決方案。那最好的辦法是什麼?我是否需要像FDKeychain這樣的鑰匙串工具?還是有沒有這樣一個簡單的方法來做到這一點Wrapper?如何在ios鑰匙串中手動存儲?

THX

+1

剛纔看了[鑰匙扣編程指南(https://developer.apple.com/library/ios/documentation/Security/Conceptual /keychainServConcepts/iPhoneTasks/iPhoneTasks.html),你會在那裏找到你的答案 – Levi

+0

你不需要像FDKeychain這樣的強制性工具,但是如果你試圖直接訪問鑰匙串,你會遇到所有的問題,我在開發FDKeychain時做了。我強烈推薦只是將它分叉(或者其他開源選項之一),然後從那裏開始,因爲第一次會出現大量邊緣情況。 –

回答

3

你可以存儲以這種方式(iOS7)手動值:

編輯:馬丁 - [R指出,如果關鍵是已經在使用SecItemAdd失敗。在這種情況下,必須調用SecItemUpdate。

NSString *key = @"full_name"; 
NSString *value = @"My Name"; 
NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding]; 
NSString *service = [[NSBundle mainBundle] bundleIdentifier]; 

NSDictionary *secItem = @{ 
    (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, 
    (__bridge id)kSecAttrService : service, 
    (__bridge id)kSecAttrAccount : key, 
    (__bridge id)kSecValueData : valueData,}; 

CFTypeRef result = NULL; 
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)secItem, &result); 
if (status == errSecSuccess){ 
    NSLog(@"value saved"); 
}else{ 
    NSLog(@"error: %ld", (long)status); 
} 

,然後你可以這樣獲取:

NSString *keyToSearchFor = @"full_name"; 
NSString *service = [[NSBundle mainBundle] bundleIdentifier]; 

NSDictionary *query = @{ 
    (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, 
    (__bridge id)kSecAttrService : service, 
    (__bridge id)kSecAttrAccount : keyToSearchFor, 
    (__bridge id)kSecReturnAttributes : (__bridge id)kCFBooleanTrue, }; 

CFDictionaryRef valueAttributes = NULL; 
OSStatus results = SecItemCopyMatching((__bridge CFDictionaryRef)query, 
              (CFTypeRef *)&valueAttributes); 
NSDictionary *attributes = (__bridge_transfer NSDictionary *)valueAttributes; 

if (results == errSecSuccess){ 
    NSString *key, *accessGroup, *creationDate, *modifiedDate, *service; 
    key = attributes[(__bridge id)kSecAttrAccount]; 
    accessGroup = attributes[(__bridge id)kSecAttrAccessGroup]; 
    creationDate = attributes[(__bridge id)kSecAttrCreationDate]; 
    modifiedDate = attributes[(__bridge id)kSecAttrModificationDate]; 
    service = attributes[(__bridge id)kSecAttrService]; 
} else { 
    NSLog(@"error: %ld", (long)results); 
} 
+0

只要注意(據我所知)SecItemAdd *失敗*如果已經有一個對象與給定的鍵。在這種情況下,必須調用SecItemUpdate。 –

+0

是的,你是對的:-) – wmvis

+0

因此,我寫FDKeychain的原因 –

相關問題