前段时间卸载了QQ,之后又重新安装了,奇怪的是账号和密码信息竟然还在,就觉得好奇怪,百度了一波,挖出了KeyChain。下面给大家分享一下我的认知和它的简单使用,有不同见解的欢迎提出。
a)什么是钥匙串?
KeyChain在Mac上大家都比较熟悉,主要进行一些敏感信息存储使用如用户名,密码,网络密码,认证令牌,Wi-Fi网络密码,VPN凭证等。iOS中钥匙扣,也有相同的功能实现,保存的信息存储在设备中,独立于每个App沙盒之外。作者这篇就简单整理下iOS中的钥匙扣。
特点:
1。相对于NSUserDefault存储一些数据,会更加安全。
2。即便App被卸载,存储的信息依旧存在,再次安装App,存储是信息依旧可以使用。
3。相同的团队ID开发,可实现多个应用共享数据。
b)结构
KeyChain和NSUserDefault 的结构类似,也是一个个键值对key-value相互映射组成的。
在iOS中每个APP 都有属于自己的KeyChain,最常用就是保存用户的账户和密码,就是记住密码,放在这里很安全,苹果负责帮我们加密再存起来,假如用NSUserDefault 保存这些秘密数据,生成的plist文件容易被拿到(----->Library/Preferences),而且还要自己做加密。
(说实话,结构这方面的理解还没达到能表达的很详细的地步,所以暂时只share这么一些,有更好的见解的欢迎指教!)
c) 使用
KeyChain 主要的用法也就是添加,删除,修改,查询。这里我自己做了个简单的封装,欢迎大家使用,话不多说,直接上代码。
ATKeyChain.h
#import <Foundation/Foundation.h>
@interfaceATKeyChain :NSObject
#pragma mark存储用户偏好设置到NSUserDefults
+(void)saveUserData:(id)data forKey:(NSString*)key;
#pragma mark读取用户偏好设置
+(id)readUserDataForKey:(NSString*)key;
#pragma mark删除用户偏好设置
+(void)removeUserDataForkey:(NSString*)key;
@end
ATKeyChain.m
#import "ATKeyChain.h"
@implementation ATKeyChain
#pragma mark ----public method
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)key {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword,(id)kSecClass,
key, (id)kSecAttrService,
key, (id)kSecAttrAccount,
(id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,
nil];
}
#pragma mark ----写入
// 说明: 该封装 添加与更新 为同一方法, 不进行判断, 直接先删除后添加
+(void)saveUserData:(id)data forKey:(NSString*)key{
NSMutableDictionary *keychainQuery = [self getKeychainQuery:key];
SecItemDelete((CFDictionaryRef)keychainQuery);
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}
#pragma mark ----读取
+(id)readUserDataForKey:(NSString*)key; {
id data = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:key];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
data = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
} @catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", key, e);
} @finally {
}
}
if (keyData)
CFRelease(keyData);
return data;
}
#pragma mark ----删除
+(void)removeUserDataForkey:(NSString*)key{
NSMutableDictionary *keychainQuery = [self getKeychainQuery:key];
SecItemDelete((CFDictionaryRef)keychainQuery);
}
@end
调用
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
[userInfo setObject:@"Mars_pananting" forKey:@"userName"];
[userInfo setObject:@"12345678" forKey:@"password"];
//添加
[ATKeyChain saveUserData:userInfo forKey:@"userInfo"];
//读取
NSMutableDictionary *result =[ATKeyChain readUserDataForKey:@"userInfo"];
NSLog(@"result ==%@",result);
//移除
[ATKeyChain removeUserDataForkey:@"userInfo"];
好了,以上我就是我对KeyChain 的简单总结。希望能给大家带来帮助。