android sqlcipher 加密,Android 数据库加密 SQLCipher使用方法

赵经国
2023-12-01

android sqlcipher使用方法

最近在做数据库加密,遇到了些问题,特此记录

greendao 支持数据库加密

网址https://greenrobot.org/greendao/documentation/database-encryption/

sqlcipher 网址:https://www.zetetic.net/sqlcipher/

sqlcipher 如何依赖在android

网址:https://www.zetetic.net/sqlcipher/sqlcipher-for-android/

as依赖 compile ‘net.zetetic:android-database-sqlcipher:3.5.9@aar’

每次在操作数据库前,初始化sqlcipher 所以我放在了application下

sqlitedatabase.loadlibs(appapplication.this);

在操作数据库时与sqlitedatabase 基本一样,唯一的区别就是打开数据库,需要密码 首先打开一个加密的数据库

sqlcipher 打开加密数据库

net.sqlcipher.database.sqlitedatabase sqlitedatabase = net.sqlcipher.database.sqlitedatabase.opendatabase(file.getabsolutepath(), password, null,

sqlitedatabase.open_readwrite

| sqlitedatabase.create_if_necessary

| sqlitedatabase.no_localized_collators, new sqlitedatabasehook() {

@override

public void prekey(net.sqlcipher.database.sqlitedatabase sqlitedatabase) {

}

@override

public void postkey(net.sqlcipher.database.sqlitedatabase sqlitedatabase) {

//操作数据与 android sqlitedatabase 用法一致

}

});

//greendao 操作数据库时 用这个方法 打开加密的库

openhelper.getencryptedwritabledb(contents.db_key);

openhelper.getencryptedreadabledb(contents.db_key);

greendao 中结合 sqlcipher 用法:

/**

* 获取可读数据库

*/

private database getreadabledatabase() {

if (contents.db_release) {

dbencrypt.getinstences().encrypt(uiutil.getcontext(), contents.db_key);

return openhelper.getencryptedreadabledb(contents.db_key);

} else {

return openhelper.getreadabledb();

}

}

/**

* 获取可写数据库

*/

private database getwritabledatabase() {

if (contents.db_release) {

dbencrypt.getinstences().encrypt(uiutil.getcontext(), contents.db_key);

return openhelper.getencryptedwritabledb(contents.db_key);

} else {

return openhelper.getreadabledb();

}

}

做完后遇到一个尴尬的问题,第一次进去时确实能显示,没毛病,当把进程杀死后在进去,都报错。。。

net.sqlcipher.database.sqliteexception: file is not a database: , while compiling: select count(*) from sqlite_master;

查询多次后发现 是加密 解密时出问题,当数据库原来未加密时用此方法打开,会报错。所以在查询数据之前,先把未加密的数据库加密,再去查询

代码附上:

/**

* 加密数据库

* created by han on 2018/4/10

* email:yin13753884368@163.com

* csdn:https://blog.csdn.net/yin13753884368/article

* github:https://github.com/yin13753884368

*/

public class dbencrypt {

public static dbencrypt dbencrypt;

private boolean isopen = true;

public static dbencrypt getinstences() {

if (dbencrypt == null) {

synchronized (dbencrypt.class) {

if (dbencrypt == null) {

dbencrypt = new dbencrypt();

}

}

}

return dbencrypt;

}

/**

* 如果有旧表 先加密数据库

*

* @param context

* @param passphrase

*/

public void encrypt(context context, string passphrase) {

file file = new file("/data/data/" + context.getpackagename() + "/databases/db_name");

if (file.exists()) {

if (isopen) {

try {

file newfile = file.createtempfile("sqlcipherutils", "tmp", context.getcachedir());

net.sqlcipher.database.sqlitedatabase db = net.sqlcipher.database.sqlitedatabase.opendatabase(

file.getabsolutepath(), "", null, sqlitedatabase.open_readwrite);

db.rawexecsql(string.format("attach database '%s' as encrypted key '%s';",

newfile.getabsolutepath(), passphrase));

db.rawexecsql("select sqlcipher_export('encrypted')");

db.rawexecsql("detach database encrypted;");

int version = db.getversion();

db.close();

db = net.sqlcipher.database.sqlitedatabase.opendatabase(newfile.getabsolutepath(),

passphrase, null,

sqlitedatabase.open_readwrite);

db.setversion(version);

db.close();

file.delete();

newfile.renameto(file);

isopen = false;

} catch (exception e) {

isopen = false;

}

}

}

}

}

 类似资料: