+

Search Tips | Advanced Search

For up-to-date product documentation, see the IBM MobileFirst Foundation Developer Center.


Encrypting data on the device

To enable the encryption of local data stores on mobile devices, we must make updates to our application to include encryption capabilities and create encrypted data stores.

Parent topic: Migrating apps storing mobile data in Cloudant with IMFData or Cloudant SDK


Encrypting data on iOS devices


Procedure

  1. Obtain the encryption capabilities with CocoaPods.

    1. Open your Podfile and add the following line:

      BEFORE (with IMFData/CloudantToolkit):

        pod 'IMFDataLocal/SQLCipher'

      AFTER (with Cloudant Sync):

        pod 'CDTDatastore/SQLCipher'

      For more information, see the CDTDatastore encryption documentation.

    2. Run the following command to add the dependencies to your application.

      pod install

  2. To use the encryption feature within a Swift application, add the following imports to the associated bridging header for the application: BEFORE (with IMFData/CloudantToolkit):

      #import <CloudantSync.h>
      #import <CloudantSyncEncryption.h>
      #import <CloudantToolkit/CloudantToolkit.h>
      #import <IMFData/IMFData.h> 

    AFTER (with Cloudant Sync):

      #import <CloudantSync.h>
      #import <CloudantSyncEncryption.h>

  3. Initialize your local store for encryption with a key provider.

    Warning: If you change the password after creating the database, an error occurs because the existing database cannot be decrypted. We cannot change your password after the database has been encrypted. You must delete the database to change passwords.

    BEFORE (with IMFData/CloudantToolkit):

      //Get reference to data manager
      IMFDataManager *manager = [IMFDataManager sharedInstance];
      NSString *name = @"automobiledb";
      NSError *error = nil;
      
      // Initalize a key provider
      id<CDTEncryptionKeyProvider> keyProvider = [CDTEncryptionKeychainProvider providerWithPassword: @"passw0rd" forIdentifier: @"identifier"];
      
      //Initialize local store
      CDTStore *localStore = [manager localStore: name withEncryptionKeyProvider: keyProvider error: &error];

      let manager = IMFDataManager.sharedInstance()
      let name = "automobiledb"
      
      let keyProvider = CDTEncryptionKeychainProvider(password: "passw0rd", forIdentifier: "identifier")
      var store:CDTStore?
      do {
          store = try manager.localStore(name, withEncryptionKeyProvider: keyProvider)
      } catch let error as NSError {
          // Handle error
      }

    AFTER (with Cloudant Sync):

      // Get reference to datastore manager
      CDTDatastoreManager *datastoreManager = existingDatastoreManager;
      NSString *name = @"automobiledb";
      NSError *error = nil;
      
      // Create KeyProvider
      id<CDTEncryptionKeyProvider> keyProvider = [CDTEncryptionKeychainProvider providerWithPassword: @"passw0rd" forIdentifier: @"identifier"];
      
      //Create local store
      CDTDatastore *datastore = [datastoreManager datastoreNamed:name withEncryptionKeyProvider:keyProvider error:&error];

      // Get reference to datastore manager
      let datastoreManager:CDTDatastoreManager = existingDatastoreManager
      let name:String  = "automobiledb"
      
      //Create local store
      var datastore:CDTDatastore?
      let keyProvider = CDTEncryptionKeychainProvider(password: "passw0rd", forIdentifier: "identifier")
      do{
          datastore = try datastoreManager.datastoreNamed(name, withEncryptionKeyProvider: keyProvider)
      }catch let error as NSError{
          // Handle error
      }

  4. When we are replicating data with an encrypted local store, we must initialize the CDTPullReplication and CDTPushReplication methods with a key provider.

    BEFORE (with IMFData/CloudantToolkit):

      //Get reference to data manager
      IMFDataManager *manager = [IMFDataManager sharedInstance];
      NSString *databaseName = @"automobiledb";
      
      // Initalize a key provider
      id<CDTEncryptionKeyProvider> keyProvider = [CDTEncryptionKeychainProvider providerWithPassword:@"password" forIdentifier:@"identifier"];
      
      // pull replication
      CDTPullReplication *pull = [manager pullReplicationForStore: databaseName withEncryptionKeyProvider: keyProvider];
      
      
      // push replication
      CDTPushReplication *push = [manager pushReplicationForStore: databaseName withEncryptionKeyProvider: keyProvider];

      //Get reference to data manager
      let manager = IMFDataManager.sharedInstance()
      let databaseName = "automobiledb"
      
      // Initalize a key provider
      let keyProvider = CDTEncryptionKeychainProvider(password: "password", forIdentifier: "identifier")
      
      // pull replication
      let pull:CDTPullReplication = manager.pullReplicationForStore(databaseName, withEncryptionKeyProvider: keyProvider)
      
      
      // push replication
      let push:CDTPushReplication = manager.pushReplicationForStore(databaseName, withEncryptionKeyProvider: keyProvider)

    AFTER (with Cloudant Sync):

    Replication with an encrypted database requires no changes from replication with an unencrypted database.

Android


Encrypting data on Android devices

To encrypt data on an Android device, obtain encryption capabilities by including the correct libraries in your application. Then, we can initialize your local store for encryption and replicate data.


Procedure

  1. Add the Cloudant Toolkit library as a dependency in your build.gradle file: BEFORE (with IMFData/CloudantToolkit):

      repositories {
          mavenCentral()
      }
      
      dependencies {
          compile 'com.ibm.mobile.services:cloudant-toolkit-local:1.0.0'
      }

    AFTER (with Cloudant Sync):

      repositories {
          mavenLocal()
          maven { url "http://cloudant.github.io/cloudant-sync-eap/repository/" }
          mavenCentral()
      }
      
      dependencies {
          compile group: 'com.cloudant', name: 'cloudant-sync-datastore-core', version:'0.13.2'
          compile group: 'com.cloudant', name: 'cloudant-sync-datastore-android', version:'0.13.2'
          compile group: 'com.cloudant', name: 'cloudant-sync-datastore-android-encryption', version:'0.13.2'
      }

  2. Download the SQLCipher for Android v3.2 .jar and .so binary files and include them in your application in the appropriate folders within your app structure:

    1. Add libraries. Add the shared library files and SQLCipher archive to the jniLibs folder under your Android app directory.
    2. Add the required ICU compressed file to the assets folder in your app.
    3. Add sqlcipher.jar as a file dependency. From the app folder menu in Android studio, select the Dependencies tab under Open Module Settings.
  3. Initialize your local store for encryption with a key provider.

    Warning: If you change the password after you create the database, an error occurs because the existing database cannot be decrypted. We cannot change your password after the database is encrypted. You must delete the database to change passwords.

    BEFORE (with IMFData/CloudantToolkit):Android

      // Get reference to DataManager
      DataManager manager = DataManager.getInstance();
      
      // Initalize a key provider
      KeyProvider keyProvider = new AndroidKeyProvider(getContext(),"password","identifier");
      
      // Create local store
      String databaseName = "automobiledb";
      Task<Store> storeTask = manager.localStore(databaseName, keyProvider);
      storeTask.continueWith(new Continuation<Store, Void >() {
          @Override
          public Void then(Task<Store> task) throws Exception {
              if (task.isFaulted()) {
                  // Handle error
              } else {
                  // Do something with Store
                  Store store = task.getResult();
              }
              return null;
           }
      });

    AFTER (with Cloudant Sync):Android

      // Load SQLCipher libs
      SQLiteDatabase.loadLibs(context);
      
      // Create DatastoreManager
      File path = context.getDir("databasedir", Context.MODE_PRIVATE);
      DatastoreManager manager = new DatastoreManager(path.getAbsolutePath());
      
      // Create encrypted local store
      String name = "automobiledb";
      
      KeyProvider keyProvider = new AndroidKeyProvider(context,"passw0rd","identifier");
      Datastore datastore = manager.openDatastore(name, keyProvider);

  4. When we are replicating data with an encrypted local store, we must pass a KeyProvider object into the pullReplicationForStore() or pushReplicationForStore() method.

    BEFORE (with IMFData/CloudantToolkit):Android

      //Get reference to data manager
      DataManager manager = DataManager.getInstance();
      String databaseName = "automobiledb";
      
      // Initalize a key provider
      KeyProvider keyProvider = new AndroidKeyProvider(getContext(),"password","identifier");
      
      // pull replication
      Task<PushReplication> pullTask = manager.pullReplicationForStore(databaseName, keyProvider);
      
      // push replication
      Task<PushReplication> pushTask = manager.pushReplicationForStore(databaseName, keyProvider);

    AFTER (with Cloudant Sync):

    Replication with an encrypted database requires no changes from replication with an unencrypted database.