热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

sqlcipher_export没有导出我的表-sqlcipher_exportdidn'texportmytables

Iamusingsqlciperwithandroidtoencryptanexistingsqlitedb,andranintoaproblemthatthee

I am using sqlciper with android to encrypt an existing sqlite db, and ran into a problem that the encrypted db didn't contain my tables, it only contains sqlite_master and android_metadata.

我使用sqlciper与android加密现有的sqlite数据库,并遇到加密数据库不包含我的表的问题,它只包含sqlite_master和android_metadata。

My original db looks like:

我原来的db看起来像:

shell@umts_spyder:/sdcard $ sqlite3 d000000.dat
sqlite3 d000000.dat
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from sqlite_master;
select * from sqlite_master;
table|android_metadata|android_metadata|2|CREATE TABLE android_metadata (locale TEXT)
table|PageData|PageData|3|CREATE TABLE PageData(File_Path TEXT NOT NULL UNIQUE, File_Content BLOB)
index|sqlite_autoindex_PageData_1|PageData|4|

I paste my encrypting code below, use empty key("") to open the plain db, if using null, NullPointerException raised(For both plain db I mentioned in the end of my post):

我粘贴下面的加密代码,使用空键(“”)打开普通数据库,如果使用null,则引发NullPointerException(对于我在帖子末尾提到的两个普通数据库):

File plain = new File(mDbPath); /* /sdcard/d0000000.dat */
File encrypt = new File(plain.getParent(), "encrypted.dat");
encrypt.delete();
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(mDbPath, "", null);
String sql = String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s'", encrypt.getPath(), mvKey.getText().toString()); // key is qqqqqqqq
db.execSQL(sql);
db.rawQuery("SELECT sqlcipher_export('encrypted')", null);
db.execSQL("DETACH DATABASE encrypted");

and below is the the code I used to test the encrypted db, there is only "android_metadata, " in the output, my table PageData lost. If I use "select * from PageData" directly, it raises no such table exception:

以下是我用来测试加密数据库的代码,输出中只有“android_metadata”,我的表PageData丢失了。如果我直接使用“select * from PageData”,则不会引发这样的表异常:

File file = new File(Environment.getExternalStorageDirectory(), "encrypted.dat");
if(!file.exists())
{
    mvBrowse.setText("not exist");
    return;
}
String key = mvKey.getText().toString();
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(file, key, null);
Cursor cursor = db.rawQuery("SELECT * FROM sqlite_master", null);
String str = new String();
while(cursor.moveToNext())
{
    str += cursor.getString(1)+", ";
}
mvBrowse.setText(str); // output is "android_metadata, "
cursor.close();
db.close();

The encrypting should work, because if I open encrypted.dat with empty("") key, it raise "file is encrypted or is not a database" exception, but I can read sqlite_master and android_metadata table with correct key.

加密应该工作,因为如果我用empty(“”)键打开encrypted.dat,它会引发“文件加密或不是数据库”异常,但我可以用正确的密钥读取sqlite_master和android_metadata表。

I Confirmed the path I tested is the same one I write encryption to;

我确认我测试的路径与我编写的加密路径相同;

Tested creating plain db by sqlcipher, using empty key:

使用空键测试由sqlcipher创建普通数据库:

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(file, "", null); /* /sdcard/d000000.dat */
db.execSQL("CREATE TABLE PageData(File_Path TEXT NOT NULL UNIQUE, File_Content BLOB)");

As well as creating it by standard sqlite tools(SQLite Export Professional, and I didn't use BLOB field in this case, just only TEXT and INTEGER);

以及通过标准的sqlite工具创建它(SQLite Export Professional,我在这种情况下没有使用BLOB字段,只有TEXT和INTEGER);

And tested with two API versions, "SQLCipher for Android v2.2.2" and "SQLCipher for Android v3.0.0".

并测试了两个API版本,“SQLCipher for Android v2.2.2”和“SQLCipher for Android v3.0.0”。

I also tried to apply the Decrypt precedure as describled in http://sqlcipher.net/sqlcipher-api/ to a encrypted db.

我还尝试将http://sqlcipher.net/sqlcipher-api/中描述的Decrypt程序应用于加密的数据库。

All above got the same result. Will somebody help me? I beleive there is some tiny wrong inside but I can't figure it out.

以上都得到了相同的结果。有人会帮助我吗?我相信里面有一些小错,但我无法弄明白。

1 个解决方案

#1


5  

Finally, I get fixed my problem, by learning from https://github.com/sqlcipher/sqlcipher-android-tests/blob/master/src/main/java/net/zetetic/tests/ImportUnencryptedDatabaseTest.java. The problem was, when executing the encrypting precedure, one must NOT use execSQL or rawQuery, but use a new introduced method "rawExecSQL. To be clear, the following code just work fine:

最后,我通过学习https://github.com/sqlcipher/sqlcipher-android-tests/blob/master/src/main/java/net/zetetic/tests/ImportUnencryptedDatabaseTest.java来解决我的问题。问题是,在执行加密过程时,必须不要使用execSQL或rawQuery,而是使用新引入的方法“rawExecSQL。要清楚,以下代码可以正常工作:

    String sql = String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s'", encrypt.getPath(), mvKey.getText().toString());
    db.rawExecSQL(sql);
    db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
    db.rawExecSQL("DETACH DATABASE encrypted");

推荐阅读
author-avatar
sunshinechenxm
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有