SecKeyChain项和SecRecord在设备和模拟器上调试之间的差异,Xamarin iOS

时间:2017-01-04 16:28:46

标签: ios xamarin.ios keychain

我正在Xamarin.iOS中创建一个使用SecKeyChain的应用程序。在其中,我试图将用户凭据作为SecRecord保存到KeyChain,然后再访问它。当应用程序启动时,它将检查KeyChain中是否有任何已保存的凭据,并决定是否提示手动登录。

调用SecKeyChain.Add时,返回成功。但是,在应用程序SecKeyChain.QueryAsRecord强制关闭失败后,错误代码为AuthFailed。这只发生在设备上,而模拟器成功。

另一个问题与创建的SecRecord有关。在DeviceSimulator上调试时创建的对象之间存在严重差异。创建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捆绑包签名我有一个签名身份和配置文件,自定义权利字段为空。

我是否遗漏了访问设备钥匙串的信息,或者问题与其他问题有关?

如果我错过了什么,请告诉我,并提前感谢你。

1 个答案:

答案 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

此外,查看SecAccessControlCreateWithFlagshttps://developer.apple.com/reference/security/1394452-secaccesscontrolcreatewithflags)的Apple文档可能也很有用,因为您使用的是自定义保护&旗帜

以下是您正在使用的组合的摘录:

SecAccessible.WhenPasscodeSetThisDeviceOnly保护意味着:

  

只有在设备解锁时才能访问钥匙串中的数据。仅在设备上设置密码时才可用。

SecAccessControlCreateFlags.TouchIDCurrentSet标志表示:

  

使用Touch ID访问当前注册的手指的约束。 Touch ID必须可用且至少有一根手指注册。如果添加或删除手指,则项目无效。

至于在模拟器中使用钥匙串,我不会依赖于那里的一致行为。还没有TouchID或密码,因此钥匙串项属性&使用它们的访问控制标志(因为它是你的情况)不会起作用。

长话短说,在使用钥匙串开发安全性时,最安全的方法是在实际设备上进行,以确保应用程序在用户中的行为符合预期。手中。但是,如果您想在模拟器上进行开发,请使用默认标记(或使用Apple的示例作为灵感)并在转移到生产时切换到更安全的标记。