Я использую SecureEnclave
на iOS для шифрования / дешифрования моего секретного ключа и сохранения его в UserPreferences
. Он был успешно настроен и зашифрован. Но всякий раз, когда я пытаюсь расшифровать данные, я получаю следующую ошибку:
Ошибка домена = NSOSStatusErrorDomain Code = -50 \ "ECIES: не удалось расшифровать данные aes-gcm \" UserInfo = {NSDescription = ECIES: не удалось расшифровать данные aes-gcm}
После долгих поисков я нашел несколько ссылок, но они не помогают. Эта проблема Github говорит о проблеме. В нем говорится,
Кроме того, в 10.3 возникла проблема с расшифровкой больших объемов данных с помощью kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM. Я подал отчет об ошибке, и это было исправлено в iOS 11. :)
Но я использую iPhone 8 с iOS 12.2, и проблема все еще существует.
Эти два вопроса SO, здесь и здесь предоставляют некоторые детали, но я не могу их расшифровать. Плюс я пользуюсь 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
}
Любая помощь высоко ценится. Спасибо.