iOS -- keyChain

來源:互聯網
上載者:User

標籤:sdi   bridge   bubuko   enc   修改   imp   att   增刪改查   取資料   

最近寫新項目,想搞一點高大上的,用keyChain來儲存使用者資訊

keyChain的好處是可以使用蘋果的加密來保證資訊的安全,而且可以在app被刪除之後保留資訊,有傳言在iOS10中keychain中的資料會隨app一起刪除,但是我用iOS11測試的結果是依然保留資料的

keyChain的另一個特性是同一個開發人員帳號下的應用可以共用資料,這個我目前用不到

 

keyChain雖然有很多優點,但是讀寫資訊還是挺麻煩的,需要兩個string的認證,這相對於plist檔案中的key-value相對來說麻煩一點

而且現在的應用一般不保留使用者密碼,而是用token來驗證使用者身份,所以目前keychain對我來說沒有什麼用

 

 

但是我還是要寫一下keychain的使用方法哎嘿嘿

 

 

keychain是用SQLite進行儲存的。用蘋果的話來說是一個專業的資料庫,加密我們儲存的資料,可以通過metadata(attributes)進行高效的搜尋。keychain適合儲存一些比較小的資料量的資料,如果要儲存大的資料,可以考慮檔案的形式儲存在磁碟上,在keychain裡面儲存解密這個檔案的密鑰。

keychain的類型
  • kSecClassGenericPassword
  • kSecClassInternetPassword
  • kSecClassCertificate
  • kSecClassKey
  • kSecClassIdentity

不同類型對應的屬性:

既然蘋果是採用SQLite去儲存的,那麼以上這些不同item的attribute可以理解是資料庫裡面表的欄位。那麼對keychain的操作其實也就是普通資料庫的增刪改查了。這樣也許就會覺得那些API也沒那麼難用了。

 

下面是我寫的keychainmanager類

#import <Foundation/Foundation.h>@interface KeyChainManager : NSObject+(void)addInfoWith:(NSString *)info           account:(NSString *)account           service:(NSString *)service;+(void)deleteInfoWithAccount:(NSString *)account                     service:(NSString *)service;+(void)changeInfoWith:(NSString *)info              account:(NSString *)account              service:(NSString *)service;+(NSString *)getInfoWithAccount:(NSString *)account                        service:(NSString *)service;@end

 

#import "KeyChainManager.h"@implementation KeyChainManager

/*

 向keychain中添加item

 info是需要儲存的資訊

 account,service是確認item的標識符,keychain通過這兩個值來確定一個item,進行增刪改查

 */

+(void)addInfoWith:(NSString *)info           account:(NSString *)account           service:(NSString *)service{        if (!info) {        info = @"";    }    if (!account || [account isEqualToString:@""]) {        NSLog(@"向keychain中添加item失敗原因是kSecAttrAccount不存在");        return;    }    if (!service || [service isEqualToString:@""]) {        NSLog(@"向keychain中添加item失敗原因是kSecAttrService不存在");        return;    }            NSDictionary *query = @{(__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleWhenUnlocked,                            (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,                            (__bridge id)kSecValueData : [info dataUsingEncoding:NSUTF8StringEncoding],                            (__bridge id)kSecAttrAccount :account,                            (__bridge id)kSecAttrService : service,                            };        OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil);    if (status == errSecSuccess) {        NSLog(@"向keychain中添加item成功");    }else{        NSLog(@"向keychain中添加item失敗%d",status);    };    }//刪除keychain中item+(void)deleteInfoWithAccount:(NSString *)account                     service:(NSString *)service{        if (!account || [account isEqualToString:@""]) {        NSLog(@"刪除keychain中item失敗原因是kSecAttrAccount不存在");        return;    }    if (!service || [service isEqualToString:@""]) {        NSLog(@"刪除keychain中item失敗原因是kSecAttrService不存在");        return;    }            NSDictionary *query = @{                            (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,                            (__bridge id)kSecAttrAccount :account,                            (__bridge id)kSecAttrService : service,                            };        OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query);    if (status == errSecSuccess) {        NSLog(@"刪除keychain中item成功");    }else{        NSLog(@"刪除keychain中item失敗%d",status);    };    }//修改keychain中item資料+(void)changeInfoWith:(NSString *)info              account:(NSString *)account              service:(NSString *)service{        if (!info) {        info = @"";    }    if (!account || [account isEqualToString:@""]) {        NSLog(@"修改keychain中item資料失敗原因是kSecAttrAccount不存在");        return;    }    if (!service || [service isEqualToString:@""]) {        NSLog(@"修改keychain中item資料失敗原因是kSecAttrService不存在");        return;    }        NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,                            (__bridge id)kSecAttrAccount :account,                            (__bridge id)kSecAttrService : service,                            };    NSDictionary *update = @{                             (__bridge id)kSecValueData : [info dataUsingEncoding:NSUTF8StringEncoding],                             };        OSStatus status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update);    if (status == errSecSuccess) {        NSLog(@"修改keychain中item資料成功");    }else{        NSLog(@"修改keychain中item資料失敗%d",status);    };    }//擷取keychain中item資料+(NSString *)getInfoWithAccount:(NSString *)account                        service:(NSString *)service{        if (!account || [account isEqualToString:@""]) {        NSLog(@"擷取keychain中item資料失敗原因是kSecAttrAccount不存在");        return nil;    }    if (!service || [service isEqualToString:@""]) {        NSLog(@"擷取keychain中item資料失敗原因是kSecAttrService不存在");        return nil;    }        NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,                            (__bridge id)kSecReturnData : @YES,                            (__bridge id)kSecMatchLimit : (__bridge id)kSecMatchLimitOne,                            (__bridge id)kSecAttrAccount :account,                            (__bridge id)kSecAttrService : service,                            };        CFTypeRef dataTypeRef = NULL;        OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &dataTypeRef);        if (status == errSecSuccess) {        NSString *pwd = [[NSString alloc] initWithData:(__bridge NSData * _Nonnull)(dataTypeRef) encoding:NSUTF8StringEncoding];        NSLog(@"擷取keychain中item資料成功==result:%@", pwd);        return pwd;    }else{        NSLog(@"擷取keychain中item資料失敗%d",status);        return nil;    };    }@end

 

 

 keychain可以進行應用間的資料共用

同一個開發人員帳號下的應用可以共用存在keychain中的資料

這裡需要到capabilities>keychain sharing

開啟keychain sharing

可以看到有一個group,添加你想要擷取資料的應用A的identifer,就可以擷取它在keychain中的資料

可以對應用A的資料進行增刪改查,但是這對應用A來說不是很安全

 

 

iOS - keychain 詳解及變化

https://www.cnblogs.com/junhuawang/p/8194484.html

 

聊聊iOS Keychain

https://www.cnblogs.com/xiongwj0910/p/7151258.html

 

iOS -- keyChain

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.