我有一个iOS应用程序,它将一些敏感信息存储在钥匙串中.在将值写入钥匙串时,我收到错误代码-34018.
我目前正在使用Apple的iOS KeyChainItemWrapper类.
以下两行代码都接收相同的错误代码.
OSStatus res1 = SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes);
OSStatus res = SecItemUpdate((__bridge CFDictionaryRef)updateItem, (__bridge CFDictionaryRef)tempCheck);
Run Code Online (Sandbox Code Playgroud)
这个问题不是每次都会发生,而是间歇性地发生.一旦我收到此错误,我就无法再将任何值写入钥匙串.
我打印了错误描述,如下所示:
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:res userInfo:nil];
Run Code Online (Sandbox Code Playgroud)
这就是错误打印出来的:
Error: Error Domain=NSOSStatusErrorDomain Code=-34018 "The operation couldn’t be completed. (OSStatus error -34018.)"
Run Code Online (Sandbox Code Playgroud) Apple已在其GenericKeyChain示例代码中提供了KeyChainItemWrapper类.在SO上有一个ARC'ed解决方案,我试图遵循:包装器存储在iOS上的KeyChain中.
包装器的用法如下:
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"F11-email-auth" accessGroup:nil];
[keychain setObject:[emailTextfield text] forKey:(__bridge id)(kSecMatchEmailAddressIfPresent)];
[keychain setObject:[passwordTextfield text] forKey:(__bridge id)(kSecClassGenericPassword)];
Run Code Online (Sandbox Code Playgroud)
接受带有电子邮件文本字段的行.但是密码的第二行崩溃,出现以下异常.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Couldn't add the Keychain Item.'
*** First throw call stack:
(
0 CoreFoundation 0x01b445e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018c78b6 objc_exception_throw + 44
2 CoreFoundation 0x01b44448 +[NSException raise:format:arguments:] + 136
3 Foundation 0x014a823e -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 Feeltracker 0x000053b3 -[KeychainItemWrapper writeToKeychain] + 899
5 Feeltracker 0x00004700 -[KeychainItemWrapper …Run Code Online (Sandbox Code Playgroud) 我们使用本机密钥链包装类来存储和检索密钥链中的值.但在某些情况下,该值将被删除/清空.
我们在我们的应用中启用了以下项目
performfetchwithcompletionhandler代码中未使用/添加的方法)上述方案是否可能对钥匙串项目产生影响,或者是否存在可能导致钥匙串项目被删除的其他方案.
objective-c cllocationmanager ios keychainitemwrapper background-fetch
我正在尝试写入iOS中的钥匙串,每当我在设备上测试时尝试写入钥匙串时,我会收到-50错误代码作为SecItemAdd的结果.
我自己首先尝试实现这样的机制,并且在多次出错之后,我尝试了KeychainItemWrapper,认为我做错了什么.但是使用KeychainItemWrapper也给了我相同的错误代码:( KeychainItemWrapper的ARCified版本,https://gist.github.com/dhoerl/1170641 )
line 305: NSAssert( result == noErr, @"Couldn't add the Keychain Item." );
结果是-50,这和我自己尝试时得到的结果相同.这是我如何使用包装器(访问组是我的应用程序ID)
keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"data" accessGroup:@"my.app.identifier"];
purchasedPacks = [keychain objectForKey:@"packs"];
if(purchasedPacks == nil){
[keychain setObject:[[NSMutableArray alloc] init] forKey:@"packs"];
}
Run Code Online (Sandbox Code Playgroud)
我首先想到可能设置一个可变数组会有问题,但尝试一个字符串也会以同样的方式失败.可能是问题的原因是什么?
谢谢,可以.
叹了口气,整个下午我一直在努力......这是我的噩梦:
我正在尝试使用Apple制作的KeychainItemWrapper.但我将其Objective-C代码"翻译"为Swift:
import Foundation
import Security
class MyKeychainItemWrapper: NSObject {
var keychainItemData: NSMutableDictionary?
var genericPasswordQuery: NSMutableDictionary = NSMutableDictionary()
init(identifier: String, accessGroup: String?) {
super.init()
// Begin Keychain search setup. The genericPasswordQuery leverages the special user
// defined attribute kSecAttrGeneric to distinguish itself between other generic Keychain
// items which may be included by the same application.
genericPasswordQuery.setObject(kSecClassGenericPassword, forKey: kSecClass)
genericPasswordQuery.setObject(identifier, forKey: kSecAttrGeneric)
// The keychain access group attribute determines if this item can be shared
// amongst multiple apps whose …Run Code Online (Sandbox Code Playgroud) Apple的GenericKeychain示例在iOS钥匙串中保存用户名和密码.它使用kSecAttrAccount用户名和kSecValueData密码.
是否所有数据项都放在钥匙串中加密,因此kSecAttrAccount在此示例中包含/ username?
我问,因为我不希望公开帐户名称.
我想将访问令牌存储到钥匙串.但我得到了错误:Couldn't add the Keychain Item.'
我检查了stackoverflow上的一些帖子,如: 在keychain中存储电子邮件不可能(KeychainItemWrapper)
mycode的:
let a = NSKeyedArchiver.archivedData(withRootObject: "980a872c17a075367357e25e88c1c0476417092a")
let keyWrapper = KeychainItemWrapper.init(identifier: "23123123", accessGroup: nil)
keyWrapper?.setObject(a, forKey: kSecValueData)
Run Code Online (Sandbox Code Playgroud)
我尝试添加这个
keyWrapper?.setObject(kSecAttrAccessible, forKey: kSecAttrAccessible)
Run Code Online (Sandbox Code Playgroud)更改kSecValueData到kSecAttrGeneric
我正在使用swift 3.0运行Xcode 8.任何提示都谢谢你!
编辑 ===========================
Viruss mca的回答开启共享钥匙串权利只为我工作一次:(
我想使用"secitemadd"在钥匙串中添加一些项目,但我首先需要知道,如果这是线程安全的.
我已经阅读了apple 的文档,但我无法找到任何说明它是否是线程安全的.
我正在使用ios钥匙串(keychainItemWrapper/ SSKeychain)来存储我的应用程序的登录令牌并保持登录状态.目前,我NSDictionary在包含我的令牌,令牌到期和刷新令牌的钥匙串中存储了一个简单的内容.我将它序列化为NSData并使用存储kSecValueData.我还设置了kSecAttrAccount和kSecAttrService,但不使用那些权威性.
这种方法效果很好,大约95%的时间都是如此.问题是随机,不可预测和零星地,当我请求它来检索令牌时,钥匙串不会返回数据.通常在距离应用程序适度的时间之后重新打开它.它不一定是在后台,也不是在任何特定的延迟之后.
询问我当它具体失败NSData的下方,返回<>来代替<ABCD EFGH IJKL ....>.我认为这是零.因此,代码认为用户未登录并立即将其丢弃在我的应用程序的注册/登录登录页面上,没有注销错误,令牌到期错误等.如果我最小化应用程序,然后重新打开,它几乎总是获得正确的钥匙串信息和用户再次登录.
遇到这会产生令人困惑的体验.这也意味着用户无法保持这种真正的100%登录状态,偶尔会被随机注销.我一直无法预测或调试它,更改钥匙串库,如下所示,并没有为我修复它.它适用于我和几个TestFlight用户,以及我们目前的生产应用程序.
有关如何维护钥匙串完整性和加载100%时间的任何建议?我们准备在令牌上实现NSUserDefaults备份存储,以便在这些情况下使用,我真的不想这样做来存储身份验证令牌.
储存:
// load keychain
KeychainItemWrapper *keychainItem = [KeychainItemWrapper keyChainWrapperForKeyID:kcIdentifier];
NSString *firstLaunch = [keychainItem objectForKey: (__bridge id)(kSecAttrAccount)];
if (firstLaunch == nil){
// initialize if needed
[keychainItem setObject:email forKey: (__bridge id)(kSecAttrAccount)];
[keychainItem setObject:kcIdentifier forKey: (__bridge id)kSecAttrService];
[keychainItem setObject:(id)kSecAttrAccessibleAfterFirstUnlock forKey:(id)kSecAttrAccessible];
}
// serialize "auth" NSDictionary into NSData and store
NSString *error;
NSData *dictionaryData = [NSPropertyListSerialization dataFromPropertyList:auth format:NSPropertyListXMLFormat_v1_0 …Run Code Online (Sandbox Code Playgroud) 当我尝试将项目添加到Keychain时,我在iOS10上发现此崩溃***断言失败 - [KeychainItemWrapper writeToKeychain]
在iOS 9.3上我把密钥写在钥匙串中没有问题谢谢