Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data Encryption

I have a question about Core Data encryption. I'm storing some sensitive user data in a Core Data SQLite database. The critical values are all transformables and I'm using AES256 to encrypt and decrypt them 'on the fly', including an individual IV for every value. The encryption key is the SHA512 hash of the password the user has chosen. This works very well so far.

Now about the user password. When the user launches the app he is asked for his password. The password is being hashed with SHA512 and stored in the iOS keychain. For every write or read operation the NSValueTransformer will get the password from the keychain. If the app is being closed, I delete the password hash from the keychain.

In my Core Data database I have a special entity which has a random number != 0 as it's only value. To test if the user has entered the correct password I fetch this entity and read the number. If it is =! 0, I know that the password was correct because when the decryption fails the NSValueTransformer always returns 0.

Now my actual questions: Would you consider this a good approach on encryption? How else would you test if the entered password is correct?

I'm a little concerned that storing the password hash in the keychain while the app is running makes everything slower, because the NSValueTransformer has to access the keychain all the time. Would it be sufficiently secure to just keep the password hash in memory, so it'll be deleted when the app closes?

like image 353
el3ktro Avatar asked Feb 15 '13 23:02

el3ktro


People also ask

How secure is Core Data?

Core Data makes no guarantees regarding the security of persistent stores from untrusted sources and cannot detect whether files have been maliciously modified. The SQLite store offers slightly better security than the XML and binary stores, but it should not be considered inherently secure.

Does Core Data use encryption?

Core Data doesn't support encrypting attributes that already exist in your CloudKit schema, or attributes that represent relationships between entities. You can also set this property using the Allow Cloud Encryption attribute in the Attributes inspector of the Core Data model editor.

What are the two types of data encryption?

There are two types of encryption in widespread use today: symmetric and asymmetric encryption. The name derives from whether or not the same key is used for encryption and decryption.

What is Core Data used for?

Core Data is a framework that you use to manage the model layer objects in your application. It provides generalized and automated solutions to common tasks associated with object life cycle and object graph management, including persistence.


1 Answers

You shouldn't use the hash of the password, hashes are designed to be fast so it's (comparatively) easy to do a brute-force attack. Use a key derivation function like PBKDF2.

Don't use a key directly derived from the password as an encryption key. If the user changes the password, you need to reencrypt all data and backups become worthless. Use a randomly generated encryption key that you encrypt with a key encryption key based on the password.

I'm not so sure about storing the hash in the keychain instead of just holding it in memory. The last time I looked into this, it was comparetively easy to decrypt the keychain. And every attacker that can read the memory of your running app will most likely be able to snoop on the keychain access or the decrypted data. Just keep it in memory and make sure to wipe the memory if the app suspends into background etc. This holds obviously also true for every piece of decrypted data.

[EDIT: @JeffLockhart to clarify the procedure for a master encryption key] you generate a random key to encrypt your data, let's call it key A. You could use SecRandomCopyBytes to generate key A, see Apple's CryptoExcercise for a usage example. You use key A to encrypt the user data. To save key A, you have to encrypt key A with a second key B. You shouldn't use the password directly as key B, because of fast brute-force or dictionary attacks. So you derive a key from the password with a PBKDF, like in this stackoverflow answer. You then encrypt key A with key B, e.g. using CCCrypt. You save the encrypted key A and the salt used to derive key B it. To decrypt, the user enters the password, you derive key B using the password and the salt. You decrypt key A using the derived key B. Hope that clarifies.

like image 156
HBu Avatar answered Oct 25 '22 05:10

HBu