I'm storing some key/value-pairs as Strings in CoreData which - in a newer version - should now be encrypted. To not alone relying on Apples DataProtection I now want to encrypt the data before storing with RNCryptor and with the help of the ValueTransformer class.
However, the transform-functions are not called, neither debug-outputs nor breakpoints are triggered. The strings are now stored as data objects, but can be read in plain text in binary representation - so they are obviously not encrypted.
Here is what I changed:
import Foundation
import RNCryptor
class EncryptedStringTransformer : ValueTransformer {
let password = "SuperSecurePassword"
override class func allowsReverseTransformation() -> Bool{
return true
}
func transformedValue(value: String?) -> NSData? {
guard let data = value else {
return nil
}
let encryptData = Data(data.utf8)
let ciphertext = RNCryptor.encrypt(data: encryptData, withPassword: password)
return ciphertext as NSData
}
func reverseTransformedValue(value: NSData?) -> String? {
guard value != nil else {
return "nil"
}
do {
let originalData = try RNCryptor.decrypt(data: (value! as Data), withPassword: password)
return String(data: originalData, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!
} catch {
print(error)
return "nil"
}
}
}
So, the app continues to work flawlessly, and all database objects can be stored and retrieved (with the difference that they are now stored as a Data object rather than a String). I'm checking the SQLite database directly with »DB Browser for SQLite«.
The expected behavior would be encrypted entries in CoreData. Can someone tell me what I am missing? Some tutorials I found don't do any additional implementations and the few articles here on StackOverflow aren't helping either with this issue.
I tried to change the output data from the transform-functions from Data to NSData, with no result. Am I missing something, so that the ValueTransformer is actually called? Any hint would be highly appreciated!
You haven't overridden the correct methods of ValueTransformer
. Your methods are:
func transformedValue(value: String?) -> NSData?
func reverseTransformedValue(value: NSData?) -> String?
The correct methods are:
func transformedValue(_ value: Any?) -> Any?
func reverseTransformedValue(_ value: Any?) -> Any?
The big hint that you're implementing the wrong methods is that you didn't need to add the override
keyword.
BTW, this expression:
encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!
can be replaced with:
encoding: .uf8
It would also likely be better to replace your return "nil"
with return nil
; it's a String?
, so it can be nil
if things go wrong.