检索钥匙串中的数据以获取在 ios 中不起作用的特定服务

Posted

技术标签:

【中文标题】检索钥匙串中的数据以获取在 ios 中不起作用的特定服务【英文标题】:Retrieve data in keychain for particular service not working in ios 【发布时间】:2017-05-18 07:41:24 【问题描述】:

我将用户名和密码存储在钥匙串中。这是我的代码

保存和获取

我正在尝试使用服务存储多个用户名和密码

点击登录按钮时

[keychain setObject:@"facebookLogin" forKey:(id)kSecAttrService];
[keychain setObject:username forKey:(id)kSecAttrAccount];
[keychain setObject:password forKey:(id)kSecValueData];

[keychain setObject:@"appLogin" forKey:(id)kSecAttrService];
[keychain setObject:username forKey:(id)kSecAttrAccount];
[keychain setObject:password forKey:(id)kSecValueData];

点击显示按钮时

NSLog(@"%@", [keychain objectForKey:(id)kSecAttrAccount]);
NSLog(@"%@", [keychain objectForKey:(id)kSecValueData]);

如何获取 Facebook 登录和应用登录存储的用户名和密码?

我想存储 cookie 值。

[keychain setObject:@"cookieString" forKey:(id)kSecAttrService];
[keychain setObject:myCookie forKey:(id)kSecValueData];

这是存储值的正确方法吗?

任何帮助表示赞赏...

【问题讨论】:

ios 中使用 PDKeychainBindings 作为漂亮的 explained with coding example here。 我正在使用 Apple 的 KeychainWrapper 我们不能用它吗? 【参考方案1】:

这应该可行:

将项目保存到钥匙串:

KeychainItemWrapper *login = [[KeychainItemWrapper alloc] initWithIdentifier:@"login" accessGroup:nil];

[wrapper setObject:username1 forKey:(__bridge id)kSecAttrAccount];
[wrapper setObject:password1 forKey:(__bridge id)kSecValueData];
[wrapper setObject:kSecAttrAccessibleAlwaysThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];

KeychainItemWrapper *facebookLogin = [[KeychainItemWrapper alloc] initWithIdentifier:@"facebooklogin" accessGroup:nil];

[wrapper setObject:username2 forKey:(__bridge id)kSecAttrAccount];
[wrapper setObject:password2 forKey:(__bridge id)kSecValueData];
[wrapper setObject:kSecAttrAccessibleAlwaysThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];

从钥匙串中检索项目:

// Create respective KeychainItemWrapper objects with identifiers you want to retrieve from

KeychainItemWrapper *login = [[KeychainItemWrapper alloc] initWithIdentifier:@"login" accessGroup:nil];

NSData *passwordData1 = [login objectForKey:(__bridge id)kSecValueData];
NSString *passwordString1 = [[NSString alloc] initWithData:passwordData1 encoding:NSUTF8StringEncoding];
NSLog(@"%@", passwordString1);

KeychainItemWrapper *facebookLogin = [[KeychainItemWrapper alloc] initWithIdentifier:@"facebooklogin" accessGroup:nil];

NSData *passwordData2 = [facebookLogin objectForKey:(__bridge id)kSecValueData];
NSString *passwordString2 = [[NSString alloc] initWithData:passwordData2 encoding:NSUTF8StringEncoding];
NSLog(@"%@", passwordString2);

使用initWithIdentifier 存储您喜欢的不同类别的项目。您可以选择包含或省略kSecAttrService,就像您在问题中使用的那样。 initWithIdentifier 够用就好了。

注意

在这里,kSecAttrAccessible 非常重要,因为钥匙串项目具有不同级别的访问安全性。如果您的手机启用了 touchId/passcode,请使用此常量(kSecAttrAccessibleAlwaysThisDeviceOnly)从任何地方访问钥匙串项目,即无需解锁您的设备。

【讨论】:

我存储了两个用户名和密码,因为我的应用程序中有两个登录名(社交和自己的),如果我用不同的服务名称存储它,旧值将被覆盖,因为键值相同。我们如何存储两者并使用服务名称检索? 请查看我更新的答案。这应该可以很好地满足您将多个类别的项目添加到钥匙串的要求。【参考方案2】:

自 iOS 10.3 beta 2 起,应用的钥匙串条目将在应用被卸载时被删除。确认在Apple Developer Forums。

【讨论】:

以上是关于检索钥匙串中的数据以获取在 ios 中不起作用的特定服务的主要内容,如果未能解决你的问题,请参考以下文章

Keychainitemwrapper 类中的 SecItemCopyMatching 条件失败,因此无法检索钥匙串中保存的值

iOS 钥匙串中的项目能否在应用程序卸载和重新安装后继续存在?

如何在ios钥匙串中手动存储?

滑动以返回在 ios 中的颤振 webview 中不起作用

访问钥匙串中的安全项目有时会在 iOS 中返回错误 -25308 (errSecInteractionNotAllowed)

Tableview 文本字段中的 iOS 在 for 循环中获取值在 ios 7 中不起作用,但在 iOS 8 中起作用