Apple、iOS 13、CryptoKit、Secure Enclave - 在使用私钥之前强制执行生物识别身份验证

Apple, iOS 13, CryptoKit, Secure Enclave - Enforce biometric authentication ahead of private key usage

我正在使用 Apple 的新 cryptokit 库,并试图让一个基本用例正常工作。

目标:我想通过 cryptokit 在安全飞地中创建一个私钥,将密钥的引用存储在 iOS 设备的密钥链中并确保只有在用户通过某种生物识别身份验证方法对自己进行身份验证后,才能在安全飞地中重新初始化密钥。

当前状态:到目前为止,我可以通过以下代码在安全飞地中初始化私钥:

var privateKeyReference = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init();

此外,我可以从钥匙链中存储和检索相应私钥的引用。检索引用后,我可以使用以下代码重新初始化安全区域中的私钥:

var privateKeyReference = getPrivateKeyReferenceFromKeyChain();
var privateKey = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init(
   dataRepresentation: privateKeyReference
);

到目前为止,一切都按预期进行,所有使用私钥的加密操作都成功了。

现在,据我了解备用 documentation by Apple,我应该可以将私钥的第一次初始化修改为如下内容。

let authContext = LAContext();
let accessCtrl = SecAccessControlCreateWithFlags(
   kCFAllocatorDefault,
   kSecAttrAccesibleWhenUnlockedThisDeviceOnly,
   [.privateKeyUsage, .userPresence, .biometryCurrentSet],
   nil
);
var privateKeyReference = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init(
   accessControl: accessCtrl!,
   authenticationContext: authContext
);

从而确保私钥只能在用户通过某种生物认证方法对自己进行认证时才能重新初始化。初始初始化仍然可以正常工作,没有任何错误。

问题: 但是加上前面的代码,我没有任何生物认证提示,重新初始化后根本无法使用私钥。每当我尝试使用重新初始化的密钥执行某些加密操作时,都会记录以下错误,例如一些签名:

Error Domain=CryptoTokenKit Code=-9 "setoken: unable to sign digest" UserInfo={NSLocalizedDescription=setoken: unable to sign digest})

据我从 here, I think that Code=-9 refers to the "authenticationNeeded" 错误猜测。

问题:有人可以指点我一些文档或教程如何实现我正在寻找的东西或向我解释我的东西我失踪了?

谢谢!

交叉-Post:https://forums.developer.apple.com/message/387746

经过几天的耐心等待,我终于得到了苹果开发支持的答复。他们建议使用以下方法,与我的方法略有不同:

var error: Unmanaged<CFError>? = nil;
let accessCtrl = SecAccessControlCreateWithFlags(
   nil,
   kSecAttrAccesibleAfterFirstUnlockThisDeviceOnly,
   [.privateKeyUsage, .biometryCurrentSet],
   &error
);
var privateKeyReference = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init(
   accessControl: accessCtrl
);

此外,同时发布了 iOS 版本 13.1.3,并且在升级我的设备后,上述代码开始运行。因此,要么我的代码和 Apple 的代码之间存在细微差别,要么与更新有关。尽管如此,它现在正在工作。