如何在ios钥匙串中手动存储?
Posted
技术标签:
【中文标题】如何在ios钥匙串中手动存储?【英文标题】:How to store manually in ios keychain? 【发布时间】:2013-12-14 19:09:36 【问题描述】:对于我的应用程序,我必须以安全的方式存储用户名/密码,并认为将其存储在系统钥匙串中的最佳解决方案。最好的方法是什么?我是否需要强制使用像 FDKeychain 这样的钥匙串工具,或者是否有一种简单的方法可以在没有这样的 Wrapper 的情况下做到这一点?
谢谢
【问题讨论】:
阅读Keychain Programming Guide,您会在那里找到答案 您不需要像 FDKeychain 这样的强制性工具,但如果您尝试自己直接访问钥匙串,您将遇到我在开发 FDKeychain 时遇到的所有问题。我强烈建议您只分叉它(或其他开源选项之一)并从那里开始,因为您第一次会错过很多边缘情况。 【参考方案1】:您可以通过这种方式手动存储值(ios7):
编辑:Martin R 指出,如果密钥已在使用中,则 SecItemAdd 失败。在这种情况下,必须调用 SecItemUpdate。
NSString *key = @"full_name";
NSString *value = @"My Name";
NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding];
NSString *service = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *secItem = @
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService : service,
(__bridge id)kSecAttrAccount : key,
(__bridge id)kSecValueData : valueData,;
CFTypeRef result = NULL;
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)secItem, &result);
if (status == errSecSuccess)
NSLog(@"value saved");
else
NSLog(@"error: %ld", (long)status);
然后你可以像这样检索它:
NSString *keyToSearchFor = @"full_name";
NSString *service = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *query = @
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService : service,
(__bridge id)kSecAttrAccount : keyToSearchFor,
(__bridge id)kSecReturnAttributes : (__bridge id)kCFBooleanTrue, ;
CFDictionaryRef valueAttributes = NULL;
OSStatus results = SecItemCopyMatching((__bridge CFDictionaryRef)query,
(CFTypeRef *)&valueAttributes);
NSDictionary *attributes = (__bridge_transfer NSDictionary *)valueAttributes;
if (results == errSecSuccess)
NSString *key, *accessGroup, *creationDate, *modifiedDate, *service;
key = attributes[(__bridge id)kSecAttrAccount];
accessGroup = attributes[(__bridge id)kSecAttrAccessGroup];
creationDate = attributes[(__bridge id)kSecAttrCreationDate];
modifiedDate = attributes[(__bridge id)kSecAttrModificationDate];
service = attributes[(__bridge id)kSecAttrService];
else
NSLog(@"error: %ld", (long)results);
【讨论】:
请注意(据我所知)SecItemAdd fails 如果已经存在具有给定键的对象。在这种情况下,必须调用 SecItemUpdate。 这就是我写FDKeychain的原因以上是关于如何在ios钥匙串中手动存储?的主要内容,如果未能解决你的问题,请参考以下文章