-
Notifications
You must be signed in to change notification settings - Fork 365
Encryption
YapDatabase supports two different forms of encryption:
- whole-database encryption utilizing SQLCipher
- object encryption via the serializer & deserializer
SQLCipher is a SQLite extension that transparently encrypts the entire database, and is available under a BSD-style license. SQLCipher support has been added as a Cocoapod subspec. Simply change your Podfile:
pod 'YapDatabase/SQLCipher'
If you aren't using the SQLCipher subspec, your project won't compile the encryption configuration options to prevent the case of accidentally trying to use encryption when support is not available.
Once the project is configured to use SQLCipher, you then need to tell YapDatabase the passphrase. You do this by setting the passphraseBlock of YapDatabaseOptions.
YapDatabaseOptions *options = [[YapDatabaseOptions alloc] init];
options.corruptAction = YapDatabaseCorruptAction_Fail;
options.passphraseBlock = ^{
// You can also do things like fetch from the keychain in here
return @"super secure passphrase";
};
self.database = [[YapDatabase alloc] initWithPath:databasePath
objectSerializer:NULL
objectDeserializer:NULL
metadataSerializer:NULL
metadataDeserializer:NULL
objectSanitizer:NULL
metadataSanitizer:NULL
options:options];The passphraseBlock helps prevent storing the credentials in memory any longer than necessary. This block will be executed on database setup, and when new connections are made to the database.
An alternative to using SQLCipher is to utilize the serializer & deserializer to encrypt objects on-the-fly. This technique may work for you if your database needs are minimal and specific. However it is important to understand exactly what is and what is NOT encrypted:
-
The object itself will be encrypted, and will be stored as a blob of encrypted data.
And you have full control over the encryption technique that is used. -
The collection & key of every object will still be in plaintext.
This may be fine if you're only using UUID's, for example. -
Views are kinda sorta encrypted, depending on your situation.
A YapDatabaseView actually stores an array of int64_t rowid's. These rowids are the primary keys for the main database table, which means they can be associated with the collection & key (which, again, are in plaintext). So whether or not this is a concern is largely application specific. -
Secondary Indexes would not be encrypted.
So anything you explicitly store via YapDatabaseSecondaryIndex would be in plaintext. -
Full Text Search would not be encrypted.
So any string you pull out for YapDatabaseFullTextSearch would be in plaintext.
All these caveats is why we stress that the technique only works if your database needs are minimal and specific. But if that's the case, then setup is quite easy:
YapDatabaseSerializer serializer = ^(NSString *collection, NSString *key, id object){
NSData *clearData = [NSKeyedArchiver archivedDataWithRootObject:object];
NSData *encryptedData = /* add encryption here */
return encryptedData;
};
YapDatabaseDeserializer deserializer = ^(NSString *collection, NSString *key, NSData *encryptedData){
NSData *clearData = /* add decryption here */
id object = [NSKeyedUnarchiver unarchiveObjectWithData:clearData];
return object;
};And that's all there is to it!