How to safely use SQLite databases in Android applications and encrypt them with SQLCipher.

Estimated read time 11 min read

Android has built-in SQLite lightweight relational database, which can store, retrieve and manage structured data in Android applications. SQLite is a serverless, zero-configuration, transactional SQL database engine ideal for use on mobile devices and desktop applications.

SQLite features:

  1. “Lightweight” : SQLite does not require a separate server process or operating system level configuration. It can directly read and write files on the disk, which is very efficient and suitable for use on mobile devices with limited resources.
  2. “ACID transactions” : SQLite supports ACID transactions, providing atomicity, consistency, isolation and durability. This ensures that data integrity is maintained even in the event of a failure.
  3. “Powerful SQL functions” : Supports most standard SQL92 functions, including indexes, triggers, views, etc.
  4. “Easy to integrate” : In Android, SQLite has been deeply integrated into the system and can be easily used in applications.
  5. “API provided by Android” : Android provides a set of APIs for operating SQLite, including SQLiteOpenHelperclasses for managing database creation and version control.
  6. “Data persistence” : Using SQLite, you can ensure that the data can still be retained even after the application is closed or the device is restarted.

Android’s built-in SQLite database does not implement encryption. You can easily export the database file created by the application and open the database file through a visualization tool to view the table structure and data of the database. There is a certain risk of data leakage. This security problem can be solved with the help of SQLCipher.

SQLCipher use

SQLCipher is an open source, free database encryption solution based on the popular database management system SQLite, adding powerful encryption capabilities. SQLCipher uses the AES-256 algorithm to encrypt the entire SQLite database, including all tables, columns, and data within it, so that only users with the correct keys can decrypt and access the data.

SQLCipher provides a transparent encryption layer to encrypt the database without changing the way you use the existing SQLite API. Operate the SQLite database as usual, and all read and write operations will automatically convert between encryption and decryption to ensure the security of data during transmission and storage. Even if the database file is stolen, the data content cannot be directly read, providing higher security and preventing data leakage and unauthorized access.

SQLCipher also features cross-platform support and can be used on multiple operating systems and platforms, including mobile devices (such as Android and iOS) and desktop applications (such as Windows, macOS and Linux ). SQLCipher can be used in different environments to encrypt and access databases.

Using SQLCipher to encrypt and decrypt the database in Android means that you have to replace the SQLite database with the SQLCipher version of the database to achieve encryption and protection of the data. SQLCipher extends the capabilities of SQLite to provide a transparent encryption layer for the database through the AES-256 encryption algorithm. Here are the basic steps to use SQLCipher in Android:

  1. “Add dependency” : Add the sqlcipher library to the project file.build.gradle
dependencies {
    implementation "net.zetetic:android-database-sqlcipher:4.5.5@aar"
}
  1. Initialize SQLCipher: When the application starts, SQLCipher needs to be initialized.
SQLiteDatabase.loadLibs(this);
  1. “Replace SQLiteOpenHelper” : Use the class provided by SQLCipher SQLiteOpenHelperto replace the one in the Android standard library SQLiteOpenHelper. The same interface provided by Android , encryption and decryption are automatically handled when opening the database.
import android.content.Context;  
import net.sqlcipher.database.SQLiteDatabase;  
import net.sqlcipher.database.SQLiteDatabase.CursorFactory;  
import net.sqlcipher.database.SQLiteOpenHelper;  
  
public class MyDatabaseHelper extends SQLiteOpenHelper {  
      
    public static final String CREATE_TABLE = "create table Book(name text, pages integer)";  
  
    public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) {  
        super(context, name, factory, version);  
    }  
  
    @Override  
    public void onCreate(SQLiteDatabase db) {  
        db.execSQL(CREATE_TABLE);  
    }  
  
    @Override  
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  
    }  
}  
  1. “Set database password” : When creating MyDatabaseHelperan instance, you need to provide a password. The password will be used to encrypt and decrypt the database.
MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "demo.db", null, 1);  
dbHelper.getWritableDatabase("123456");  
  1. “Perform database operations” : Through MyDatabaseHelperthe instance, perform database operations (such as creating tables, inserting data, querying data, etc.). SQLCipher automatically handles encryption and decryption under the hood.
//插入一本书
ContentValues values = new ContentValues();  
values.put("name", "达芬奇密码");  
values.put("pages", 566);  
db.insert("Book", null, values);  

Usage example

MyDatabaseHelper.java

public class MyDatabaseHelper extends SQLiteOpenHelper {  
      
    public static final String CREATE_TABLE = "create table Book(name text, pages integer)";  
  
    public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) {  
        super(context, name, factory, version);  
    }  
  
    @Override  
    public void onCreate(SQLiteDatabase db) {  
        db.execSQL(CREATE_TABLE);  
    }  
  
    @Override  
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  
    }  
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical" >  
      
    <Button   
        android:id="@+id/add_data"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="添加数据" />  
      
    <Button   
        android:id="@+id/query_data"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="查询数据" />  
  
</LinearLayout>  

MainActivity.java

public class MainActivity extends AppCompatActivity {  
      
    private SQLiteDatabase db;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);
        //初始化 注意不要导错包net.sqlcipher.database包下的SQLiteDatabase
        SQLiteDatabase.loadLibs(this);  
        MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "demo.db", null, 1);  
        db = dbHelper.getWritableDatabase("secret_key");  
        Button addData = (Button) findViewById(R.id.add_data);  
        Button queryData = (Button) findViewById(R.id.query_data);  
        addData.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                ContentValues values = new ContentValues();  
                values.put("name", "达芬奇密码");  
                values.put("pages", 566);  
                db.insert("Book", null, values);  
            }  
        });  
        queryData.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Cursor cursor = db.query("Book", nullnullnullnullnullnull);  
                if (cursor != null) {  
                    while (cursor.moveToNext()) {  
                        String name = cursor.getString(cursor.getColumnIndex("name"));  
                        int pages = cursor.getInt(cursor.getColumnIndex("pages"));  
                        Log.d("TAG", "book name is " + name);  
                        Log.d("TAG", "book pages is " + pages);  
                    }  
                }  
                cursor.close();  
            }  
        });  
    }  
}  

Using the API provided by SQLCipher and using Android’s native database API are almost identical in operation. SQLCipher has made a mirror for all database-related APIs in the Android SDK, allowing developers to operate SQLCipher just like operating common database files, and all data encryption and decryption operations are handled by SQLCipher behind the scenes. .

You May Also Like

More From Author

+ There are no comments

Add yours