我正在Xamarin.iOS中创建一个使用SecKeyChain的应用程序。在其中,我试图将用户凭据作为SecRecord保存到KeyChain,然后再访问它。当应用程序启动时,它将检查KeyChain中是否有任何已保存的凭据,并决定是否提示手动登录。
调用SecKeyChain.Add时,返回成功。但是,在应用程序SecKeyChain.QueryAsRecord强制关闭失败后,错误代码为AuthFailed。这只发生在设备上,而模拟器成功。
另一个问题与创建的SecRecord有关。在Device和Simulator上调试时创建的对象之间存在严重差异。创建SecRecord的代码是:
var credentialsRecord = new SecRecord(SecKind.GenericPassword)
{
Generic = NSData.FromString("record"),
Label = credentials.Username,
Account = credentials.Username,
Service = CredentialsStorageServiceName,
ValueData = NSData.FromBytes(credentials.Password.ToIntPtr(), Convert.ToUInt32(credentials.Password.Length()) * 2),
AccessControl = new SecAccessControl(SecAccessible.WhenPasscodeSetThisDeviceOnly, SecAccessControlCreateFlags.TouchIDCurrentSet)
};
var statusCode = SecKeyChain.Add(credentialsRecord);
在entitlements.plist中,我启用了钥匙串访问组,并添加了一个名为与我的虚拟Xcode项目的包标识符相同的组。在项目选项中 - > iOS捆绑包签名我有一个签名身份和配置文件,自定义权利字段为空。
我是否遗漏了访问设备钥匙串的信息,或者问题与其他问题有关?
如果我错过了什么,请告诉我,并提前感谢你。
答案 0 :(得分:1)
我与Xamarin并不是非常亲密,但由于它在C#中封装了iOS原生api,Apple自己的例子可能有所帮助(因为它基本涵盖了你所描述的相同场景): https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html#//apple_ref/doc/uid/TP30000897-CH208-SW1
此外,查看SecAccessControlCreateWithFlags
(https://developer.apple.com/reference/security/1394452-secaccesscontrolcreatewithflags)的Apple文档可能也很有用,因为您使用的是自定义保护&旗帜
以下是您正在使用的组合的摘录:
SecAccessible.WhenPasscodeSetThisDeviceOnly
保护意味着:
只有在设备解锁时才能访问钥匙串中的数据。仅在设备上设置密码时才可用。
SecAccessControlCreateFlags.TouchIDCurrentSet
标志表示:
使用Touch ID访问当前注册的手指的约束。 Touch ID必须可用且至少有一根手指注册。如果添加或删除手指,则项目无效。
至于在模拟器中使用钥匙串,我不会依赖于那里的一致行为。还没有TouchID或密码,因此钥匙串项属性&使用它们的访问控制标志(因为它是你的情况)不会起作用。
长话短说,在使用钥匙串开发安全性时,最安全的方法是在实际设备上进行,以确保应用程序在用户中的行为符合预期。手中。但是,如果您想在模拟器上进行开发,请使用默认标记(或使用Apple的示例作为灵感)并在转移到生产时切换到更安全的标记。