Android 数据库加密 SQLCipher使用方法
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; } } } } }
上一篇: ramdisk.img unpack and repack
下一篇: HTML5中的拼写检查