当前位置: 移动技术网 > IT编程>移动开发>Android > Android 数据库加密 SQLCipher使用方法

Android 数据库加密 SQLCipher使用方法

2018年12月27日  | 移动技术网IT编程  | 我要评论

与美女上司同居,爱在日月潭吻戏,塑米期货早评

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;
                    }
                }
            }
        }
    }

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网