html5 ios keychain,iOS 用keychain钥匙串保存账号、设备UUID及APP间共享

iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失。

方法:增删查改

OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef * __nullable CF_RETURNS_RETAINED result)//增

OSStatus SecItemDelete(CFDictionaryRef query) //删

OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef * __nullable CF_RETURNS_RETAINED result) //查

OSStatus SecItemUpdate(CFDictionaryRef query,

CFDictionaryRef attributesToUpdate) //改

所有方法的参数设置都需要通过CFDictionaryRef,所以创建一个专门获得NSDictionary的方法,然后通过桥接__bridge CFDictionaryRef的方式获得参数

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)key forAccessGroup:(NSString *)group{

NSMutableDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,

(__bridge id)kSecAttrService : key,

(__bridge id)kSecAttrAccount : key,

(__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock

}.mutableCopy;

if (group != nil) {

[query setObject:[self getFullAccessGroup:group] forKey:(__bridge id)kSecAttrAccessGroup];

}

return query;

}

参数太多,而且在头文件SecItem.h中有详细说明,这里就不一一详说(详说也我也说不清),比如最后一个参数:

kSecAttrAccessibleAfterFirstUnlock

Item data can only be accessed once the device has been unlocked after a restart.

This is recommended for items that need to be accesible by background applications.

Items with this attribute will migrate to a new device when using encrypted backups.

2.保存方法:

+ (BOOL)setValue:(id)value forKey:(NSString *)key forAccessGroup:(NSString *)group{

NSMutableDictionary *query = [self getKeychainQuery:key forAccessGroup:group];

[self deleteValueForKey:key forAccessGroup:group];

NSData *data = nil;

@try {

data = [NSKeyedArchiver archivedDataWithRootObject:value];

} @catch (NSException *exception) {

NSLog(@"archived failure value %@ %@",value,exception);

return NO;

}

[query setObject:data forKey:(__bridge id)kSecValueData];

OSStatus result = SecItemAdd((__bridge CFDictionaryRef)query, NULL);

return result == errSecSuccess;

}

其中,保存是先删掉之前的key,没有使用update,感觉这样简单;然后保存的value转换为NSData,如果value为自定义object,则需遵循NSSecureCoding协议,实现编码方法,如下:

@interface YTestObject : NSObject

@property (strong,nonatomic) NSString *string;

@end

#import "YTestObject.h"

@implementation YTestObject

- (NSString *)description{

return [NSString stringWithFormat:@"",_string];

}

+ (BOOL)supportsSecureCoding{

return YES;

}

- (void)encodeWithCoder:(NSCoder *)aCoder{

[aCoder encodeObject:_string forKey:@"string"];

}

- (instancetype)initWithCoder:(NSCoder *)aDecoder{

_string = [aDecoder decodeObjectForKey:@"string"];

return self;

}

@end

另外,为了防止在保存不支持NSSecureCoding协议的类时crash,使用了@try,简单介绍:

@try {

//执行的代码,其中可能有异常。一旦发现异常,则立即跳到catch执行。否则不会执行catch里面的内容

} @catch (NSException *exception) {

//除非try里面执行代码发生了异常,否则这里的代码不会执行

} @finally {

//不管什么情况都会执行,包括try catch 里面用了return ,可以理解为只要执行了try或者catch,就一定会执行 finally

}

3.keychain-access-groups

keychain允许同一个开发商的多个APP共享指定AccessGroup内的数据。

A.创建plish文件如KeychainAccessGroups.plist,添加节点key为keychain-access-groups的array,如下图:

354ea1279e68

keychain-plist.png

$(AppIdentifierPrefix)为开发者帐号对应的ID;

B.在APP target的bulibSetting里面设置Code Signing Entitlements,指向包含AceessGroup的分组信息的plist文件,如下图(这时plist需在最顶层文件夹中):

354ea1279e68

codesigning.png

4.设备UUID

有了上面的方法后,直接创建一个NSUUID保存即可;

- (NSString *)getUUID{

NSString *uuid = [YKeychain valueForKey:@"YDeviceUUID"];

if (uuid == nil) {

uuid = [NSUUID UUID].UUIDString;

[YKeychain setValue:uuid forKey:@"YDeviceUUID"];

}

return uuid;

}

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值