sqlcipher-android

Unable to open db file created using SQLCipher Android


I am trying to enable encryption for SQLite database using SQLCipher. Below is my DBHelper and MainActivity code. With this am able create the db and application is also working fine in the emulator. But when i exported the db file and tried to run under DB browser for SQLite am get an error message which is ** Could not open the file Reason: File is not a database file ** . Can anyone please help me on this ? Thanks in advance..

** DBHelper.java***

package com.example.androidsqlitesipher.Helper;

import android.content.ContentValues;
import android.content.Context;

import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.List;

public class DBHelper extends SQLiteOpenHelper {

    private static DBHelper instance;
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "ContactsDemo.db";
    public static final String TABLE_NAME = "Emails";
    public static final String COLUMN_NAME = "Email";
    public static final String PASS_PHRASE = "@123#";
    private static String SQL_CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "("
            + COLUMN_NAME + " TEXT PRIMARY KEY)";
    private static String SQL_DELETE_TABLE = "DROP TABLE IF EXITS " + TABLE_NAME;

    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    static public synchronized DBHelper getInstance(Context context){
        if(instance == null)
            instance = new DBHelper(context);
        return instance;
    }
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        sqLiteDatabase.execSQL(SQL_CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        sqLiteDatabase.execSQL(SQL_DELETE_TABLE);
        onCreate(sqLiteDatabase);
    }

    //CRUD
    public void insertNewEmail(String email){
        SQLiteDatabase db = instance.getWritableDatabase(PASS_PHRASE);

        ContentValues cv =  new ContentValues();
        cv.put(COLUMN_NAME,email);
        db.insert(TABLE_NAME,null,cv);
        db.close();
    }
    public void updateEmail(String oldEmail, String newEmail){
        SQLiteDatabase db = instance.getWritableDatabase(PASS_PHRASE);

        ContentValues cv =  new ContentValues();
        cv.put(COLUMN_NAME,newEmail);
        db.update(TABLE_NAME,cv,COLUMN_NAME+"='"+oldEmail+"'",null);
        db.close();
    }
    public void deleteEmail(String email){
        SQLiteDatabase db = instance.getWritableDatabase(PASS_PHRASE);

        ContentValues cv =  new ContentValues();
        cv.put(COLUMN_NAME,email);
        db.delete(TABLE_NAME,COLUMN_NAME+"='"+email+"'",null);
        db.close();
    }
    public List<String> getAllEmails(){
        SQLiteDatabase db = instance.getWritableDatabase(PASS_PHRASE);
        Cursor cursor = db.rawQuery(String.format("Select * from %s;",TABLE_NAME),null);
        List<String> emails = new ArrayList<>();
        if(cursor.moveToFirst()){
            while(!cursor.isAfterLast()){
                String email = cursor.getString(cursor.getColumnIndex(COLUMN_NAME));
                emails.add(email);
                cursor.moveToNext();
            }
        }
        cursor.close();
        db.close();
        return emails;
    }
}

** MainActivity.java**

package com.example.androidsqlitesipher;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.example.androidsqlitesipher.Helper.DBHelper;

import net.sqlcipher.database.SQLiteDatabase;

public class MainActivity extends AppCompatActivity {
    Button btnAdd, btnUpdate, btnDelete;
    EditText edtEmail;
    ListView lstEmails;
    String saveEmail = ""; //save current email to update/delete
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SQLiteDatabase.loadLibs(this);
        lstEmails = (ListView)findViewById(R.id.lstEmails);
        lstEmails.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                String item = (String)lstEmails.getItemAtPosition(i);
                edtEmail.setText(item);
                saveEmail = item;
            }
        });
        edtEmail = (EditText) findViewById(R.id.edtEmail);
        btnAdd = (Button)findViewById(R.id.btnAdd);
        btnUpdate = (Button)findViewById(R.id.btnUpdate);
        btnDelete = (Button)findViewById(R.id.btnDelete);

        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DBHelper.getInstance(MainActivity.this).insertNewEmail(edtEmail.getText().toString());
                reloadEmails();
            }
        });

        btnUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DBHelper.getInstance(MainActivity.this).updateEmail(saveEmail,edtEmail.getText().toString());
                reloadEmails();
            }
        });

        btnDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DBHelper.getInstance(MainActivity.this).deleteEmail(edtEmail.getText().toString());
                reloadEmails();
            }
        });

        reloadEmails();
    }
    private void reloadEmails()
    {
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1,
                android.R.id.text1,
                DBHelper.getInstance(this).getAllEmails());
        lstEmails.setAdapter(adapter);
    }
}


Solution

  • What version of SQLCipher are you using? This can be determined by using PRAGMA cipher_version

    What version of DB Browser for SQLite are you using? You'll want to use the latest release: https://github.com/sqlitebrowser/sqlitebrowser/releases/tag/v3.11.2 which supports opening both SQLCipher 3 + 4 databases.

    Once you determine which version of SQLCipher you're using, and ensure you're using the correct version of DB Browser for SQLite, select the correct corresponding SQLCipher version default encryption settings from the prompt: SQLCipher_Version_Default_Encryption_Settings