美文网首页
Android使用SQLCipher加密已有的pb文件

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

作者: jiting45 | 来源:发表于2019-04-16 14:05 被阅读0次

    我的使用场景: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文件没法用工具打开查看了,更拿不到里面的数据了。

    相关文章

      网友评论

          本文标题:Android使用SQLCipher加密已有的pb文件

          本文链接:https://www.haomeiwen.com/subject/ibavwqtx.html