我在 iOS 上使用
SecureEnclave
来加密/解密我的机密密钥并将其保存在 UserPreferences
中。已成功设置并加密数据。但每当我尝试解密数据时,都会出现以下错误:
错误域 = NSOSStatusErrorDomain 代码 = -50 \“ECIES:无法 aes-gcm 解密数据\” UserInfo = {NSDescription = ECIES:无法 aes-gcm 解密数据}
经过大量搜索,我找到了一些链接,但它们没有任何帮助。 这个 Github Issue 讨论了这个问题。它指出,
此外,在 10.3 上,使用 kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM 解密大量数据存在问题。我为此提交了一份错误报告,并在 iOS 11 中修复了它。:)
但我使用的是装有 iOS 12.2 的 iPhone 8,但仍然存在问题。
这两个问题,here和here提供了一些细节,但我无法破译它。另外,我正在使用 Swift 4。
下面是我用来加密/解密数据的相关代码。
生成密钥对
func generateKeyPair(accessControl: SecAccessControl) throws -> (`public`: SecureEnclaveKeyReference, `private`: SecureEnclaveKeyReference) {
let publicKeyParameters: [String: AnyObject] = [
kSecAttrIsPermanent as String: false as AnyObject,
kSecAttrApplicationTag as String: "com.xxx.xxx" as AnyObject,
kSecAttrLabel as String: "PublicKey" as AnyObject
]
let privateKeyParameters: [String: AnyObject] = [
(kSecAttrCanDecrypt as CFString) as String: true as CFBoolean,
kSecAttrIsPermanent as String: true as AnyObject,
kSecAttrAccessControl as String: accessControl,
kSecAttrApplicationTag as String: "com.xxx.xxx" as AnyObject,
kSecAttrLabel as String: "PrivateKey" as AnyObject
]
let parameters: [String: AnyObject] = [
kSecAttrKeyType as String: kSecAttrKeyTypeEC,
kSecAttrKeySizeInBits as String: 256 as AnyObject,
kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave,
kSecPublicKeyAttrs as String: publicKeyParameters as AnyObject,
kSecPrivateKeyAttrs as String: privateKeyParameters as AnyObject
]
var publicKey, privateKey: SecKey?
let status = SecKeyGeneratePair(parameters as CFDictionary, &publicKey, &privateKey)
print("Result = \(status) - Public Key = \(publicKey) - Private Key = \(privateKey)")
guard status == errSecSuccess else {
throw SecureEnclaveHelperError(message: "Could not generate keypair", osStatus: status)
}
return (public: SecureEnclaveKeyReference(publicKey!), private: SecureEnclaveKeyReference(privateKey!))
}
加密
@available(iOS 10.3, *)
func encrypt(_ digest: Data, publicKey: SecureEnclaveKeyReference) throws -> Data {
var error : Unmanaged<CFError>?
let result = SecKeyCreateEncryptedData(publicKey.underlying, SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM, digest as CFData, &error)
if result == nil {
throw SecureEnclaveHelperError(message: "\(error)", osStatus: 0)
}
return result as! Data
}
解密
@available(iOS 10.3, *)
func decrypt(_ digest: Data, privateKey: SecureEnclaveKeyReference) throws -> Data {
var error : Unmanaged<CFError>?
let result = SecKeyCreateDecryptedData(privateKey.underlying, SecKeyAlgorithm.eciesEncryptionStandardX963SHA256AESGCM, digest as CFData, &error)
if result == nil {
throw SecureEnclaveHelperError(message: "\(error)", osStatus: 0)
}
return result as! Data
}
非常感谢任何帮助。谢谢。
我遇到了同样的错误,发现我生成了两个不同的密钥对,其中我使用一个公钥加密数据,但使用另一个错误的私钥执行解密。因此,请确保解密操作使用与加密中使用的公钥相对应的正确私钥。
最后怎么解决的?