ios - IOS:无法从 CryptoKit SecureEnclave 私钥创建 SecKey 表示(OSStatus 错误 -50 - 从数据创建 EC 私钥失败))
问题描述
SecureEnclave
我正在尝试在with中创建一个私钥/公钥对CryptoKit
,然后保存对私钥的引用以KeyChain
供进一步使用。密钥生成完全正常:
let accessControl = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
[.privateKeyUsage],
nil
)!
let privateKey = try SecureEnclave.P256.Signing.PrivateKey(accessControl: accessControl)
// Describe the key.
let attributes = [
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeyClass: kSecAttrKeyClassPrivate
] as [String: Any]
但是当我尝试将刚刚创建的密钥转换为SecKey
稍后将其存储在钥匙串中时:
// Get a SecKey representation.
var error: Unmanaged<CFError>?
guard let secKey = SecKeyCreateWithData(key.dataRepresentation as CFData, attributes as CFDictionary, nil) else {
throw error!.takeRetainedValue()
}
它失败并出现错误:
The operation couldn’t be completed. (OSStatus error -50 - EC private key creation from data failed)
另一方面,当我删除SecureEnclave
元素并使用时,x963Representation
我能够将私钥转换为SecKey
对象:
let privateKey = P256.Signing.PrivateKey()
guard let secKey = SecKeyCreateWithData(privateKey.x963Representation as CFData, attributes as CFDictionary, nil) else {
throw error!.takeRetainedValue()
}
关于为什么会发生这种情况或我该如何解决这个问题的任何想法?
解决方案
如文档中所述,并非所有密钥都可以(直接)存储到钥匙串中。要解决此问题,您可以将原始Data
密码作为通用密码存储在钥匙串中。SecureEnclave
钥匙有点可惜。
此外,.dataRepresentation
Secure Enclave 的私钥不是 Security 框架所理解的。Secure Enclave 密钥不打算被提取(据我所知,根本无法提取)。您提取的 blob 是同一个enclave 可用于重建私钥的容器。在另一部 iPhone 上使用相同的数据不会重新创建密钥。
我不确定将此 blob 作为文件存储在设备上是否存在安全风险。因此,我建议您查看前面提到的文档并使用GenericPasswordConvertible
示例。
推荐阅读
- ios - iOS:为什么 UIApplicationProtectedDataWillBecomeUnavailable 总是不通知?
- python - 如何通过python中的第一个字符有效地将元素分组在一个巨大的列表中
- configuration - 谷歌云数据处理集群创建--properties标签的问题
- math - 你能简化二项式产品的求和吗
- node.js - NPM 漏洞 - 需要人工审核
- dictionary - 是否有众所周知的数据结构/技术来获取具有“范围”索引的地图元素?
- c++ - cout 表现出不同的行为
- android - 需要帮助将此 github 项目导入 Android Studio
- c# - DataContractJsonSerializer 在反序列化期间对字典内的 DateTime 值进行字符串化
- javascript - 在 on change 事件中将选择菜单重置为默认值