IOS KEYCHAIN
HappyMan
2014/12/30
What is KeyChain
• Keychain is an encrypted container where you can store secured information like passwords,certificates, identities, …etc.
• In iOS, each application has its own keychain.
• To share the data between apps, they should have the same Access Group in code signing entitlements.
Accessing password-protected services using a keychain in OS X
Accessing an Internet server using iPhone Keychain Services
• KeyChain 是 iOS 提供的一種安全保存私密資料的方式,整個系統的 keychain 被保存在隱秘的位置(/private/var/Keychains/keychain-2.db),其中保存的資料是經過加密的。
優點
• 每個組( keychain-access-groups )之間資料存取隔離,沒有權限的 app無法讀取他人資料,保證資料的安全
• 全域性統一儲存,即使刪除 app , keychain中的資料依然存在,下次重新安裝app還能存取
• 存儲後的資料會加密
• 同一個組的 app 可以共享 keychain 中的資料
缺點
• 刪除 app 後不會清除 keychain 裡的資料,如果儲存密碼等敏感性資料有一定的風險。(越獄後 keychain 能被導出來)
實作API
• 新增:SecItemAdd
• 尋找:SecItemCopyMatching
• 更新:SecItemUpdate
• 移除:SecItemDelete
準備資料
• -(NSMutableDictionary *) prepareDict:(NSString *)key
• {
• NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
• [dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
•
• NSData *encodedKey = [key dataUsingEncoding:NSUTF8StringEncoding];
• [dict setObject:encodedKey forKey:(__bridge id)kSecAttrGeneric];
• [dict setObject:encodedKey forKey:(__bridge id)kSecAttrAccount];
• [dict setObject:service forKey:(__bridge id)kSecAttrService];
• [dict setObject:(__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly forKey:(__bridgeid)kSecAttrAccessible];
•
• return dict;
• }
新增
• -(BOOL) insert:(NSString *)key :(NSData *)data
• {
• NSMutableDictionary *dict =[self prepareDict:key];
• [dict setObject:data forKey:(__bridge id)kSecValueData];
•
• OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dict, NULL);
• if(errSecSuccess != status) {
• NSLog(@"Unable add item with key = %@ error:%d",key,(int)status);
• }
• return (status == errSecSuccess);
• }
尋找
• -(NSData*) find:(NSString *)key
• {
• NSMutableDictionary *dict = [self prepareDict:key];
• [dict setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
• [dict setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
• CFTypeRef result = NULL;
• OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dict,&result);
•
• if(status != errSecSuccess) {
• NSLog(@"Unable to fetch item for key %@ with error: %d",key,(int)status);
• return nil;
• }
•
• return (__bridge NSData *)result;
• }
更新
• -(BOOL) update:(NSString*)key :(NSData *)data
• {
• NSMutableDictionary *dictKey =[self prepareDict:key];
•
• NSMutableDictionary *dictUpdate =[[NSMutableDictionary alloc] init];
• [dictUpdate setObject:data forKey:(__bridge id)kSecValueData];
•
• OSStatus status = SecItemUpdate((__bridge CFDictionaryRef)dictKey, (__bridge
CFDictionaryRef)dictUpdate);
• if(status != errSecSuccess) {
• NSLog(@"Unable add update with key = %@ error: %d",key,(int)status);
• }
• return (status == errSecSuccess);
• }
移除
• -(BOOL) remove:(NSString *)key
• {
• NSMutableDictionary *dict = [self prepareDict:key];
• OSStatus status = SecItemDelete((__bridgeCFDictionaryRef)dict);
• if(status != errSecSuccess) {
• NSLog(@"Unable to remove item for key %@ with error: %d",key,(int)status);
• }
• return (status == errSecSuccess);
• }
開源
• SSKeychainhttps://github.com/soffes/sskeychainStar: 1730 (2014/12/30)
• SFHFKeychainUtilshttps://github.com/kamiro/SFHFKeychainUtilsStar: 60 (2014/12/30)
• Me: 2 projects
Demo
• https://github.com/happymanx/KeyChainTest
– 1). Initialization of the class
– 2). How to Add an item to keychain
– 3). Find an item in the keychain
– 4). Update an item in the keychain
– 5). Remove an item from keychain
參考
• iOS KeyChain Tutorialhttp://hayageek.com/ios-keychain-tutorial/
• Securing and Encrypting Data on iOShttp://code.tutsplus.com/tutorials/securing-and-encrypting-data-on-ios--mobile-21263
• Basic Security in iOS 5 – Part 1http://www.raywenderlich.com/6475/basic-security-in-ios-5-tutorial-part-1
• Basic Security in iOS 5 – Part 2http://www.raywenderlich.com/6603/basic-security-in-ios-5-tutorial-part-2
參考
• iOS Keychain: Sharing data between appshttp://shaune.com.au/ios-keychain-sharing-data-between-apps/
• Keychain Group Accesshttp://useyourloaf.com/blog/2010/04/03/keychain-group-access.html
• 將密碼儲存於 KeyChainhttp://wp.me/p1my2P-3S0
• KeyChain 使用與共享數據http://blog.csdn.net/ibcker/article/details/24839143
Apple連結
• Keychain Services Programming Guidehttps://developer.apple.com/library/mac/documentation/Security/Conceptual/keychainServConcepts/
• Keychain Services Referencehttps://developer.apple.com/library/mac/documentation/Security/Reference/keychainservices/
• #WWDC14 session 711 - Keychain and Authentication with Touch ID