1

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()
}

关于为什么会发生这种情况或我该如何解决这个问题的任何想法?

4

1 回答 1

2

如文档中所述,并非所有密钥都可以(直接)存储到钥匙串中。要解决此问题,您可以将原始Data密码作为通用密码存储在钥匙串中。SecureEnclave钥匙有点可惜。

此外,.dataRepresentationSecure Enclave 的私钥不是 Security 框架所理解的。Secure Enclave 密钥不打算被提取(据我所知,根本无法提取)。您提取的 blob 是同一个enclave 可用于重建私钥的容器。在另一部 iPhone 上使用相同的数据不会重新创建密钥。

我不确定将此 blob 作为文件存储在设备上是否存在安全风险。因此,我建议您查看前面提到的文档并使用GenericPasswordConvertible示例。

于 2021-08-16T06:50:23.673 回答