使用 SecKeyGeneratePair 在 iOS 中生成密钥对失败,错误为 errSecInteractionNotAllowed
Generating key pair in iOS using SecKeyGeneratePair failed with errSecInteractionNotAllowed
在我的应用程序中,我使用 SecKeyGeneratePair
生成 RSA 密钥对。发布该应用程序后,我开始注意到在使用此功能时偶尔出现 errSecInteractionNotAllowed
错误(目前非常罕见),到目前为止仅在 iOS 10 台设备上出现。我不清楚为什么密钥对生成失败,或者我应该如何解决这个问题。此外,我找不到任何文档说明为什么密钥对生成会因此错误而失败。
这是我用来生成密钥对的代码:
guard let access = SecAccessControlCreateWithFlags(nil,
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
[],
nil) else {throw Error(description: "Failed to create access control")}
let privateAttributes = [String(kSecAttrIsPermanent): true,
String(kSecAttrApplicationTag): keyTag + self.privateKeyExtension,
String(kSecAttrAccessControl): access] as [String : Any]
let publicAttributes = [String(kSecAttrIsPermanent): true,
String(kSecAttrApplicationTag): keyTag + self.publicKeyExtension] as [String : Any]
let pairAttributes = [String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecAttrKeySizeInBits): self.rsaKeySize,
String(kSecPublicKeyAttrs): publicAttributes,
String(kSecPrivateKeyAttrs): privateAttributes] as [String : Any]
var pubKey, privKey: SecKey?
let status = SecKeyGeneratePair(pairAttributes as CFDictionary, &pubKey, &privKey)
在这段代码之后,我正在检查状态,如果不是 errSecSuccess
,我会记录一个错误,并显示函数返回的状态。这是我注意到 errSecInteractionNotAllowed
错误的地方。
那么,为什么会生成密钥对或者我可以做些什么来修复它?
谢谢,
奥马尔
两条建议:
- 尝试为您的 SecAccessControlCreateWithFlags 调用添加其他保护 class,例如
kSecAttrAccessibleAlways
,并测试该行为是否仍然发生。
- 进一步定义一个flag for your use case instead of passing an empty array. E.g. userPresence.
另外我偶然发现了这个SO post,也许你可以在那里找到一些灵感。
与 Apple Developer Support 讨论后,这里是解决方案:
let privateAttributes = [String(kSecAttrIsPermanent): true,
String(kSecAttrApplicationTag): keyTag + self.privateKeyExtension,
String(kSecAttrAccessible): kSecAttrAccessibleAlways] as [String : Any]
let publicAttributes = [String(kSecAttrIsPermanent): true,
String(kSecAttrApplicationTag): keyTag + self.publicKeyExtension,
String(kSecAttrAccessible): kSecAttrAccessibleAlways] as [String : Any]
let pairAttributes = [String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecAttrKeySizeInBits): self.rsaKeySize,
String(kSecPublicKeyAttrs): publicAttributes,
String(kSecPrivateKeyAttrs): privateAttributes] as [String : Any]
var pubKey, privKey: SecKey?
let status = SecKeyGeneratePair(pairAttributes as CFDictionary, &pubKey, &privKey)
重要的部分是 kSecAttrAccessible
,从中选择符合您需要的值 list。请注意,某些值将限制对 KeyVault 中密钥的访问。
在我的应用程序中,我使用 SecKeyGeneratePair
生成 RSA 密钥对。发布该应用程序后,我开始注意到在使用此功能时偶尔出现 errSecInteractionNotAllowed
错误(目前非常罕见),到目前为止仅在 iOS 10 台设备上出现。我不清楚为什么密钥对生成失败,或者我应该如何解决这个问题。此外,我找不到任何文档说明为什么密钥对生成会因此错误而失败。
这是我用来生成密钥对的代码:
guard let access = SecAccessControlCreateWithFlags(nil,
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
[],
nil) else {throw Error(description: "Failed to create access control")}
let privateAttributes = [String(kSecAttrIsPermanent): true,
String(kSecAttrApplicationTag): keyTag + self.privateKeyExtension,
String(kSecAttrAccessControl): access] as [String : Any]
let publicAttributes = [String(kSecAttrIsPermanent): true,
String(kSecAttrApplicationTag): keyTag + self.publicKeyExtension] as [String : Any]
let pairAttributes = [String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecAttrKeySizeInBits): self.rsaKeySize,
String(kSecPublicKeyAttrs): publicAttributes,
String(kSecPrivateKeyAttrs): privateAttributes] as [String : Any]
var pubKey, privKey: SecKey?
let status = SecKeyGeneratePair(pairAttributes as CFDictionary, &pubKey, &privKey)
在这段代码之后,我正在检查状态,如果不是 errSecSuccess
,我会记录一个错误,并显示函数返回的状态。这是我注意到 errSecInteractionNotAllowed
错误的地方。
那么,为什么会生成密钥对或者我可以做些什么来修复它?
谢谢,
奥马尔
两条建议:
- 尝试为您的 SecAccessControlCreateWithFlags 调用添加其他保护 class,例如
kSecAttrAccessibleAlways
,并测试该行为是否仍然发生。 - 进一步定义一个flag for your use case instead of passing an empty array. E.g. userPresence.
另外我偶然发现了这个SO post,也许你可以在那里找到一些灵感。
与 Apple Developer Support 讨论后,这里是解决方案:
let privateAttributes = [String(kSecAttrIsPermanent): true,
String(kSecAttrApplicationTag): keyTag + self.privateKeyExtension,
String(kSecAttrAccessible): kSecAttrAccessibleAlways] as [String : Any]
let publicAttributes = [String(kSecAttrIsPermanent): true,
String(kSecAttrApplicationTag): keyTag + self.publicKeyExtension,
String(kSecAttrAccessible): kSecAttrAccessibleAlways] as [String : Any]
let pairAttributes = [String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecAttrKeySizeInBits): self.rsaKeySize,
String(kSecPublicKeyAttrs): publicAttributes,
String(kSecPrivateKeyAttrs): privateAttributes] as [String : Any]
var pubKey, privKey: SecKey?
let status = SecKeyGeneratePair(pairAttributes as CFDictionary, &pubKey, &privKey)
重要的部分是 kSecAttrAccessible
,从中选择符合您需要的值 list。请注意,某些值将限制对 KeyVault 中密钥的访问。