你的位置:首页 > 操作系统

[操作系统]iOS keychain入门


      学了很久的iOS,一直都是明文保存用户名和密码在本地,手机一般都是自己用的,而且非越狱手机东西也不怎么能拿到数据,所以也就没在乎那么多,当然,这是不科学的。悄悄的说,这块一直不是我写的~~~

      用户隐私信息正常都是加密保存在本地,各种各样的加密方法,大家自己去找找就好了,今天介绍下keychain。

  官方文档介绍如下:

  Keychain Services provides secure storage of passwords, keys, certificates, and notes for one or more users. A user can unlock a keychain with a single password, and any Keychain Services–aware application can then use that keychain to store and retrieve passwords。

  简单的翻译下,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   else40     if(status==errSecItemNotFound)41     {42       NSLog(@"#####################not found");43       //store44       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   else70   {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 }

  测试下:

  

 

  取密码