我可以创建将在 "unlocked" 中保留一定时间的私钥吗?

Can I create private key that will stay "unlocked" for certain amount of time?

我有一个可以生成几个私钥的应用程序。当用户需要签署数据时,他们必须使用生物识别技术进行身份验证,而 Secure Enclave 使用适当的私钥对其进行签名。简单。

我有一个新要求 - 应用程序需要能够在多条数据到达设备时对其进行签名,并且用户在对第一条数据进行签名时应 进行身份验证。

所以我的问题是:

  1. 是否可以创建一个私钥,在用户使用生物识别技术进行身份验证后,它会在一定时间内保持解锁状态?如果可以,怎么做?

  2. 是否可以创建一个在程序告诉 Secure Enclave 锁定它之前一直保持解锁状态的私钥?如果可以,怎么做?

我彻底搜索了文档和堆栈溢出,但一无所获。非常感谢任何帮助!

好吧,经过大量测试,我找到了问题的答案。通常(在我的例子中),每次使用私钥时用户都需要进行身份验证。

为了能够进行批量操作,我们需要使用LAContext并设置重用时长:

let context = LAContext()
context.touchIDAuthenticationAllowableReuseDuration = 10.0 // 10 seconds

加载私钥时将上下文添加到属性中:

let attributes: [CFString: Any] = [
   // ...
   kSecUseAuthenticationContext: context
   // ...
]

var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)

然而,这有一个意想不到的行为。即使在时间限制过后,私钥仍保持“解锁”状态。使上下文无效以锁定私钥也不起作用。

为了在批量签名完成后锁定密钥,我们需要:

  1. 取消分配上下文,或重新初始化以供将来使用
  2. 使用新上下文(或没有上下文)重新加载私钥,因为私钥持有对上下文的强引用。

只有在那之后,用户才需要再次使用生物识别技术进行身份验证,所以请记住这一点。

也可以说没有必要生成新密钥。此方法适用于现有密钥。