Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions mifosng-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ dependencies {
apt "com.github.Raizlabs.DBFlow:dbflow-processor:$rootProject.raizLabsDBFlow"
compile "com.github.Raizlabs.DBFlow:dbflow-core:$rootProject.raizLabsDBFlow"
compile "com.github.Raizlabs.DBFlow:dbflow:$rootProject.raizLabsDBFlow"
// sql-cipher database encryption
releaseCompile "com.github.Raizlabs.DBFlow:dbflow-sqlcipher:$rootProject.raizLabsDBFlow@aar"
releaseCompile "net.zetetic:android-database-sqlcipher:3.5.1"

// App's Support dependencies, including test
compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion"
Expand Down Expand Up @@ -167,16 +170,17 @@ dependencies {
compile "com.squareup.retrofit2:converter-scalars:$rootProject.retrofitVersionLatest"
compile "com.squareup.retrofit2:adapter-rxjava:$rootProject.retrofitVersionLatest"
compile "com.squareup.okhttp3:okhttp:$rootProject.okHttp3Version"
compile "com.squareup.okhttp3:logging-interceptor:$rootProject.okHttp3Version"
debugCompile "com.squareup.okhttp3:logging-interceptor:$rootProject.okHttp3Version"
compile "com.jakewharton.fliptables:fliptables:$rootProject.flipTableVersion"

compile 'javax.annotation:jsr250-api:1.0@jar'

compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.4'

compile 'com.facebook.stetho:stetho:1.3.1'
compile 'com.facebook.stetho:stetho-okhttp3:1.3.1'
//facebook Stetho for Debugging with SQLite Database
debugCompile 'com.facebook.stetho:stetho:1.3.1'
debugCompile 'com.facebook.stetho:stetho-okhttp3:1.3.1'


compile 'com.joanzapata.iconify:android-iconify-material:2.1.1' // (v2.0.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ public void onCreate() {
Fabric.with(this, new Crashlytics());

Iconify.with(new MaterialModule());
//Initializing the DBFlow and SQL Cipher Encryption
//Initializing the DBFlow
FlowManager.init(new FlowConfig.Builder(this).build());

Stetho.initializeWithDefaults(this);
}

Expand Down
93 changes: 93 additions & 0 deletions mifosng-android/src/release/java/com/mifos/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* This project is licensed under the open source MPL V2.
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/

package com.mifos;

import android.app.Application;
import android.content.Context;
import android.graphics.Typeface;

import com.crashlytics.android.Crashlytics;
import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.fonts.MaterialModule;
import com.mifos.api.local.MifosDatabase;
import com.mifos.api.local.MifosSQLCipherHelper;
import com.mifos.mifosxdroid.injection.component.ApplicationComponent;
import com.mifos.mifosxdroid.injection.component.DaggerApplicationComponent;
import com.mifos.mifosxdroid.injection.module.ApplicationModule;
import com.raizlabs.android.dbflow.config.DatabaseConfig;
import com.raizlabs.android.dbflow.config.DatabaseDefinition;
import com.raizlabs.android.dbflow.config.FlowConfig;
import com.raizlabs.android.dbflow.config.FlowManager;
import com.raizlabs.android.dbflow.structure.database.DatabaseHelperListener;
import com.raizlabs.android.dbflow.structure.database.OpenHelper;

import java.util.HashMap;
import java.util.Map;

import io.fabric.sdk.android.Fabric;

/**
* Created by ishankhanna on 13/03/15.
*/
public class App extends Application {

public static final Map<Integer, Typeface> typefaceManager = new HashMap<>();

private static App instance;

ApplicationComponent mApplicationComponent;

public static Context getContext() {
return instance;
}

public static App getInstance() {
return instance;
}

public static App get(Context context) {
return (App) context.getApplicationContext();
}

@Override
public void onCreate() {
super.onCreate();
instance = this;
Fabric.with(this, new Crashlytics());

Iconify.with(new MaterialModule());
//Initializing the DBFlow and SQL Cipher Encryption
FlowManager.init(new FlowConfig.Builder(this)
.addDatabaseConfig(
new DatabaseConfig.Builder(MifosDatabase.class)
.openHelper(new DatabaseConfig.OpenHelperCreator() {
@Override
public OpenHelper createHelper(
DatabaseDefinition databaseDefinition,
DatabaseHelperListener helperListener) {
return new MifosSQLCipherHelper(
databaseDefinition, helperListener);
}
})
.build())
.build());
}

public ApplicationComponent getComponent() {
if (mApplicationComponent == null) {
mApplicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(this))
.build();
}
return mApplicationComponent;
}

// Needed to replace the component with a test specific one
public void setComponent(ApplicationComponent applicationComponent) {
mApplicationComponent = applicationComponent;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.mifos.api;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;

/**
* Created by Rajan Maurya on 16/06/16.
*/
public class MifosOkHttpClient {


public OkHttpClient getMifosOkHttpClient() {

OkHttpClient.Builder builder = new OkHttpClient.Builder();

try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = {
new X509TrustManager() {
@Override
public void checkClientTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}

@Override
public void checkServerTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};

// Install the all-trusting trust manager
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

//Set SSL certificate to OkHttpClient Builder

builder.sslSocketFactory(sslSocketFactory);

builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} catch (Exception e) {
throw new RuntimeException(e);
}

//Setting Timeout 30 Seconds
builder.connectTimeout(60, TimeUnit.SECONDS);
builder.readTimeout(60, TimeUnit.SECONDS);

//Interceptor :> Full Body Logger and ApiRequest Header
builder.addInterceptor(new MifosInterceptor());

return builder.build();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.mifos.api.local;

import com.raizlabs.android.dbflow.config.DatabaseDefinition;
import com.raizlabs.android.dbflow.structure.database.DatabaseHelperListener;
import com.raizlabs.dbflow.android.sqlcipher.SQLCipherOpenHelper;

public class MifosSQLCipherHelper extends SQLCipherOpenHelper {

public MifosSQLCipherHelper(DatabaseDefinition databaseDefinition,
DatabaseHelperListener listener) {
super(databaseDefinition, listener);
}

@Override
protected String getCipherSecret() {
return "dbflow-rules";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line of code is the problem, Secret is something that people cannot know. We need to find a way to make it secure.

Copy link
Member Author

@therajanmaurya therajanmaurya Feb 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have two ways to implement

  1. What about if we make the MD5 hash of username and password entered by the user. And save them in the custom data table on the server.
  2. Add an extra screen and give the user to enter the database encryption key after the login and save then on server and double encrypt the key and save in Shared Preference So no one can get the key other than admin.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@satyan Suggestion

One of the options could be to use user's password entry to encrypt the key on the client. So you could only decrypt with the help of user.

It adds a layer of entropy to the system. However, could mean that we ask the user for password multiple times..

Android also supports a hardware backed keychain support. You could potentially explore that as well to store the key.

Having a server backed key is a good option too. Except, in offline case, it'd be difficult to obtain. Do not store in shared preferences, as it's stored in a file on the device in clear. Easily obtained.

}
}