首页 > 技术文章 > iOS keychain存储

xiao-flag 2016-08-10 15:34 原文

 简单的翻译下,keychain可以存储密码、证书等等,至于有什么好处,呵呵哒,自己百度去吧,总结一点就是更安全,而且取的更方便吧,看app场景吧。

  本次代码,分为两段,一段为保存代码

复制代码
 1 - (BOOL)saveData:(NSString *)str
 2 {
 3     OSStatus status = noErr;
 4     NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
 5     [query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
 6     /// query one
 7     [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
 8     [query setObject:@"password" forKey:(id)kSecAttrService];
 9     CFMutableDictionaryRef outDicRef = nil;
10     status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&outDicRef);
11     if(status==noErr)
12     {
13         NSLog(@"#######################query success");
14         [query removeObjectForKey:(id)kSecMatchLimit];
15         NSLog(@"=============code   %d",SecItemDelete((CFDictionaryRef)query));
16         NSMutableDictionary *dt = [[NSMutableDictionary alloc] init];
17         [dt setObject:@"label" forKey:(id)kSecAttrLabel];
18         [dt setObject:@"password" forKey:(id)kSecAttrService];
19         [dt setObject:[str dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
20         [dt setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
21         
22         [dt setObject:@"Item label" forKey:(__bridge id)kSecAttrLabel];
23         
24         [dt setObject:@"Item description" forKey:(__bridge id)kSecAttrDescription];
25         
26         [dt setObject:@"Account" forKey:(__bridge id)kSecAttrAccount];
27         
28         [dt setObject:@"Service" forKey:(__bridge id)kSecAttrService];
29         
30         [dt setObject:@"Your comment here." forKey:(__bridge id)kSecAttrComment];
31         status = SecItemAdd((CFDictionaryRef)dt, NULL);
32         if(status==noErr)
33         {
34             NSLog(@"#######################save success");
35             return YES;
36         }
37         return YES;
38     }
39     else
40         if(status==errSecItemNotFound)
41         {
42             NSLog(@"#####################not found");
43             //store
44             NSMutableDictionary *dt = [[NSMutableDictionary alloc] init];
45             [dt setObject:@"label" forKey:(id)kSecAttrLabel];
46             [dt setObject:@"password" forKey:(id)kSecAttrService];
47             [dt setObject:[str dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
48             [dt setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
49             
50             [dt setObject:@"Item label" forKey:(__bridge id)kSecAttrLabel];
51             
52             [dt setObject:@"Item description" forKey:(__bridge id)kSecAttrDescription];
53             
54             [dt setObject:@"Account" forKey:(__bridge id)kSecAttrAccount];
55             
56             [dt setObject:@"Service" forKey:(__bridge id)kSecAttrService];
57             
58             [dt setObject:@"Your comment here." forKey:(__bridge id)kSecAttrComment];
59             status = SecItemAdd((CFDictionaryRef)dt, NULL);
60             if(status==noErr)
61             {
62                 NSLog(@"#######################save success");
63                 return YES;
64             }
65             if(outDicRef)
66                 CFRelease(outDicRef);
67             return NO;
68         }
69     else
70     {
71         NSLog(@"########################error query %d",status);
72     }
73     return NO;
74 }
复制代码

代码有些凌乱,各位将就下吧,急着去睡觉~

  读取代码如下:

复制代码
 1 - (NSString *)getData
 2 {
 3     OSStatus status = noErr;
 4     NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
 5     [query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
 6     /// query one
 7     [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
 8     [query setObject:@"Service" forKey:(id)kSecAttrService];
 9     ///如果想取到相关属性,这里必须设置。就这个地方,害我搞半天
10     [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
11     CFDictionaryRef attributes = nil;
12     ///取到属性了
13     status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&attributes);
14     if(status==noErr)
15     {
16         NSLog(@"--------%@",attributes);
17     }
18     [query removeObjectForKey:(id)kSecReturnAttributes];
19     CFDataRef outData;
20     ///取值,实际存放密码的地方,这里要设置
21     [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
22     status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&outData);
23     ///解析回来
24     NSString *str = [[NSString alloc] initWithData:(__bridge NSData *)outData encoding:NSUTF8StringEncoding];
25     return str;
26 }
复制代码

  测试下:

  

     取到属性:

  

 

  取密码

  

推荐阅读