android sqlite解密,SQlite数据库的加密与解密

本文详细介绍了如何在Android系统中实现SQLite数据库的加密,包括使用系统自带的SQLite明文存储的缺点,以及通过SQLCipher进行加密的步骤。通过替换原生库、加载SO库、设置密码等方式,实现了对数据库的加密操作。同时,提供了将已加密数据库转换为未加密文件的方法,并展示了如何在第三方DbFlow库中应用加密。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 关于SQlite

Android系统自带的SQlite是明文存储,不支持加密

二 SQlite加密方式

内容加密

主要写入读取数据时候做加密与解密的动作

缺点:

表结构暴露

无法直接搜索

数据库文件加密

对整个数据库文件加密

三 采用开源的SQLCipher进行加密

SQLCipher使用256-bit AES加密,由于其基于免费版的SQLite,主要的加密接口和SQLite是相同的,但也增加了一些自己的接口

3.1 对Android原生的数据库进行加密

(1)导入SQLCipher加密库

compile "net.zetetic:android-database-sqlcipher:3.5.9@aar"

(2)替换原生的包

* android.database.Cursor 为 net.sqlcipher.Cursor

* android.database.sqlite.SQLiteDatabase 为 net.sqlcipher.database.SQLiteDatabase

* android.database.SQLiteOpenHelper 为 net.sqlcipher.database.SQLiteOpenHelper

(3)加载SQLCipher所需要的SO库

SQLiteDatabase.loadLibs(this);

(4)获取读写对象时候附带密码

SQLiteOpenHelper.getWritableDatabase("密码"):

SQLiteOpenHelper.getReadableDatabase("密码")

3.2 对第三方DbFlow数据库进行加密

(1)替换为DbFlow加密库

// sql-cipher database encryption (optional)

compile "com.github.Raizlabs.DBFlow:dbflow-sqlcipher:${dbflow_version}"

compile "net.zetetic:android-database-sqlcipher:${sqlcipher_version}@aar"

(2)更改初始化的方法

FlowManager.init(FlowConfig.builder(this)

.addDatabaseConfig(DatabaseConfig.builder(QiDatabase.class)

.openHelper(new DatabaseConfig.OpenHelperCreator() {

@Override

public OpenHelper createHelper(DatabaseDefinition databaseDefinition, DatabaseHelperListener helperListener) {

return new SQLCipherOpenHelper(databaseDefinition, helperListener) {

@Override

protected String getCipherSecret() {

return "密码";

}

};

}

})

.build())

.build());

3.3 对未加密数据库的转换为加密的数据库

在加载SQLCipher所需要的SO库后及SQLiteDatabase.loadLibs(this)后,调用以下加密方法

/**

* 对未加密的数据库文件做加密处理

*

* @param ctxt 上下文

* @param dbName 数据库的文件名

* @param passphrase 密码

* @throws IOException

*/

public static void encrypt(Context ctxt, String dbName, String passphrase) throws IOException {

File originalFile = ctxt.getDatabasePath(dbName);

if (originalFile.exists()) {

File newFile =

File.createTempFile("sqlcipherutils", "tmp",

ctxt.getCacheDir());

SQLiteDatabase db =

SQLiteDatabase.openDatabase(originalFile.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 = SQLiteDatabase.openDatabase(newFile.getAbsolutePath(),

passphrase, null,

SQLiteDatabase.OPEN_READWRITE);

db.setVersion(version);

db.close();

originalFile.delete();

newFile.renameTo(originalFile);

}

}

3.4 对加密数据库的保存为未加密的数据库文件

/**

* 将加密数据库文件保存为非加密的数据库文件

*

* @param context 上下文

* @param dbName 数据库名

* @param password 密码

* @param decFile 待保存的目标文件

* @return

*/

public static boolean decrypt(Context context, String dbName, String password, File decFile) {

boolean flag = false;

//先清空目标文件

decFile.delete();

try {

File originalFile = context.getDatabasePath(dbName);

SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(originalFile, password, null);

if (database.isOpen()) {

database.rawExecSQL(String.format("ATTACH DATABASE '%s' as plaintext KEY '';", decFile.getAbsolutePath()));

database.rawExecSQL("SELECT sqlcipher_export('plaintext');");

database.rawExecSQL("DETACH DATABASE plaintext;");

android.database.sqlite.SQLiteDatabase sqlDB = android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(decFile, null);

if (sqlDB != null)

flag = true;

sqlDB.close();

database.close();

}

} catch (Exception e) {

e.printStackTrace();

}

return flag;

// databaseFile.delete();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值