Android使用SQLCipher加密已有的pb文件

2019-04-16  本文已影响0人  jiting45

我的使用场景:app做离线功能,相关数据是定时从服务端下载得到pb文件,但是pb文件中含有公司的数据,且该项目是to B的一个工具类项目,因此需要对pb文件做加密处理。
使用SQLCipher加密未存在的数据库很简单,而且google一下会有很多文章介绍;但是加密本地的pb文件这样的文章很少,自己实际操作过程中也遇到了问题,记录一下。SQLCipher加密的思路是:将要加密的pb文件中的所有的表全部拷贝一份并且带有密码,但是拷贝完成后需要自己删除要加密的文件,这样即使将pb文件拷贝出来也是打不开的了。
SQLCipher的集成和使用
1、首先在app的build.gradle中引入依赖:
implementation 'net.zetetic:android-database-sqlcipher:3.5.7@aar'
2、在使用SQLCipher之前要SQLiteDatabase.loadLibs(this);否则会报异常:

No implementation found for void net.sqlcipher.database.SQLiteDatabase.dbopen(java.lang.String, int) (tried Java_net_sqlcipher_database_SQLiteDatabase_dbopen and Java_net_sqlcipher_database_SQLiteDatabase_dbopen__Ljava_lang_String_2I)

我是在application中做的。
3、加密数据库(进行数据表的拷贝操作)

/**
     * 加密数据库
     *
     * @param encryptedName 加密后的文件
     * @param decryptedName 要加密的文件
     * @param key           密码
     */
    public void encryptMap(String encryptedName, String decryptedName, String key) {
        String filePath = Constants.FILE_PATH_OFFLINE_DB;
        File file = new File(filePath + "/" + encryptedName);
        // 新建加密后的数据库文件,并设置其密码key
        SQLiteDatabase dataTarget = SQLiteDatabase.openOrCreateDatabase(file, key, null);
        String path = filePath + "/" + decryptedName;
        //执行sql语句,连接未加密的数据库,并将其取别名为sourceLib,因为未加密数据库没密码,所以密码为""
        dataTarget.execSQL("attach '" + path + "' as sourceLib key '';");
            /*String passwordString = "1234"; //只能对已加密的数据库修改密码,且无法直接修改为“”或null的密码
            database.changePassword(passwordString.toCharArray());*/

        // 执行sql语句,在加密后的数据库文件中新建表,并将未加密的数据库表拷贝到新的加密数据库中,原数据库有多张表,该操作重复多少次
        dataTarget.execSQL("create table new_table as select * from sourceLib.table");
        //断开同加密后的数据库的连接
        dataTarget.execSQL("detach database 'sourceLib'");
        dataTarget.close();
    }

其中sql语句中"create table new_table as select * from sourceLib.table"的new_table是加密后的表名,table是要加密的pb文件中的表名。
加密操作完成后记得把本地的要加密的pb文件删除,否则别人还是能用之前的pb文件看到数据。
4、打开数据库

/**
     * 打开数据库(如果为空则表示数据库不存在)
     *
     * @param dbName
     * @return
     */
    public SQLiteDatabase openDatabase(String dbName) {
        String filePath = Constants.FILE_PATH_OFFLINE_DB;
        File jhPath = new File(filePath + "/" + dbName);
        //查看数据库文件是否存在
        if (jhPath.exists()) {
            //存在则直接返回打开的数据库
            sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(jhPath, ''your key'', null);
            return sqLiteDatabase;
        } else {
            return null;
        }
    }

注意SQLiteDatabase和之后操作用到的Cursor都需要引用import net.sqlcipher.database.SQLiteDatabase;
这样之后数据库相关的操作api还是和原来一样,只是此时的pb文件没法用工具打开查看了,更拿不到里面的数据了。

上一篇下一篇

猜你喜欢

热点阅读