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:
- Added and activated a new migration/database scheme
- Changed key and value column from Type String to Transformable
- Set the Value Transformer to »EncryptedStringTransformer« and the Custom Class to »String«
- and finally I added a file Encryption.swift with the following implementation:
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:The correct methods are:
The big hint that you're implementing the wrong methods is that you didn't need to add the
override
keyword.BTW, this expression:
can be replaced with:
It would also likely be better to replace your
return "nil"
withreturn nil
; it's aString?
, so it can benil
if things go wrong.