加载加密sqlite到内存
2022-04-25 10:48 一截生长 阅读(379) 评论(0) 编辑 收藏 举报背景
为了使C#更好的适配Linux,不得不将依赖从 System.Data.SQLite 转到
Microsoft.Data.Sqlite
并要求Linux程序支持加密数据库文件,但使 Microsoft.Data.Sqlite 默认不支持加密数据库文件,但是可以使用
SQLCipher, SEE 或者SQLiteCrypt 去支持加密数据库文件。
如果不是加密的数据库文件,通过下面操作将物理数据库,备份到已经创建的可分享内存数据库
var connectionString = new SqliteConnectionStringBuilder("Data Source=sampleDatabase.db") { Mode = SqliteOpenMode.ReadWriteCreate }.ToString(); var connection = new SqliteConnection(connectionString); connection.Open(); var inMemConnectionString = new SqliteConnectionStringBuilder("Data Source=InMemorySample;Mode=Memory;Cache=Shared") { Mode = SqliteOpenMode.ReadWriteCreate }.ToString(); var inMemConnection = new SqliteConnection( inMemConnectionString ); inMemConnection.Open(); connection.BackupDatabase(inMemConnection, connection.Database, connection.Database);
问题
如上操作,将加密数据库加载到内存会抛异常 SqliteException
,提示信息:
backup is not supported with encrypted databases.
解决
将带有空密码的可分享内存数据库,加载到加密的数据库,然后使用sqlcipher_export,将数据解密保存到内存数据库中,最后将加密数据库卸载, 你就可以愉快的使用内存数据库了, 但是内存数据库是不支持加密的。
var connectionString = new SqliteConnectionStringBuilder("Data Source=encrypted.db") { Mode = SqliteOpenMode.ReadWriteCreate, Password = "somePassword" }.ToString(); var connection = new SqliteConnection(connectionString); connection.Open(); var query = "ATTACH DATABASE 'file:InMemorySample?mode=memory&cache=shared' AS inMemDb KEY ''; SELECT sqlcipher_export('inMemDb'); DETACH DATABASE inMemDb;"; using var cmd = new SqliteCommand(query, connection); var res = cmd.ExecuteNonQuery(); connection.Close(); var inMemConnectionString = new SqliteConnectionStringBuilder("Data Source=InMemorySample;Mode=Memory;Cache=Shared") { Mode = SqliteOpenMode.ReadWriteCreate }.ToString(); var inMemConnection = new SqliteConnection( inMemConnectionString ); inMemConnection.Open();
转至https://www.ariank.dev/load-sqlcipher-encrypted-sqlite-databases-into-memory/