SQLite database实现加密

本文介绍了如何在VS2022的C#项目中使用SQLitePCLRaw库实现数据库加密,包括安装Nuget包、在连接字符串中添加密码、查看加密后的数据以及验证数据库是否加密的方法。
摘要由CSDN通过智能技术生成

注意:以下操作以VS2022为开发工具,以C#为开发语言。

数据加密原因

软件在使用的各个场景,很多都需要数据具有保密性,于是对于数据库就需要加密。特别是在某些特定领域或存储敏感数据尤其如此。

SQLite加密实现

SQLite加密有两种方式,其一是使用SQLite的收费版本,其可以实现加密;另一种就是使用免费的SQLitePCLRaw 来实现。收费版由于囊中羞涩,就不多说了,说说使用SQLitePCLRaw怎么实现加密。

加密实现步骤

首先在所需要的项目安装Nuget包SQLitePCLRaw.bundle_e_sqlcipher,当前最新版本为2.1.7。

然后只需要连接SQLite的字符串中添加 Password=YourPassword 即可,以下为使用EFCore时重写OnConfiguring实现加密的示例,其它方式可参考此示例进行相应操作:

        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlite($"Data Source={DbPath};Password={Consts.DbPwd}");

加密后数据如何查看?

通过上述操作加密后使用Sqlite查看工具就需要输入密码才可进行查看数据,以SQLiteStudio为例进行说明。

1.添加数据库时,Database type一定要选择SQLCipher,然后再选择你的Sqlite的db文件。

2.在下图中的Password中录入密码(Sqlite加密是没有用户名的),然后点击下图中左下角的Test connection进行测试,确认密码是否正确。

密码正确的话,点击上图中的OK,即可成功将数据库添加到SQLiteStudio中。后续的数据查看及相应操作与未加密的SQLite完全一致。

验证database是否加密?

至于验证是否加密,若安装了SQLiteStudio,并将db文件关连了SQLite Studio,那么双击 .db文件是不能直接打开的,双击时会出现报错:[17:45:06] Could not add database F:\backup\Source\win10-x64\DataBase\your.db: file is not a database; file is not a database; file is not a database.

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Spring Boot 中实现 SQLite 加密功能,可以使用 SQLite 的 SQLCipher 扩展。SQLCipher 是一个基于 SQLite加密数据库,提供了加密和解密 SQLite 数据库的方法。 下面是实现步骤: 1. 添加 SQLCipher 依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>net.zetetic</groupId> <artifactId>android-database-sqlcipher</artifactId> <version>4.4.0</version> </dependency> ``` 2. 配置 SQLite 数据库 在 application.properties 文件中配置 SQLite 数据库,设置加密密码等信息,例如: ```properties spring.datasource.driver-class-name=org.sqlite.JDBC spring.datasource.url=jdbc:sqlite:test.db spring.datasource.username= spring.datasource.password= spring.datasource.tomcat.initial-size=1 spring.datasource.tomcat.max-active=5 spring.datasource.tomcat.min-idle=1 spring.datasource.tomcat.max-idle=5 # Enabling SQLCipher for SQLite spring.jpa.database-platform=com.example.sqlite.Platform spring.datasource.sql-script-encoding=UTF-8 ``` 其中,`com.example.sqlite.Platform` 是一个自定义的数据库平台类,用于启用 SQLCipher 扩展。在这个类中,我们需要指定 SQLCipher 的加密密码,例如: ```java public class Platform extends SQLiteDialect { private static final String CIPHER_ALGORITHM = "256"; @Override public String getAddPrimaryKeyString(String constraintName) { return " primary key"; } @Override public boolean supportsIdentityColumns() { return true; } @Override public boolean hasDataTypeInIdentityColumn() { return false; } @Override public String getIdentityColumnString() { return "integer"; } @Override public String getIdentitySelectString() { return "select last_insert_rowid()"; } @Override public String getSequenceNextValString(String sequenceName) { return "select " + sequenceName + ".nextval from dual"; } @Override public String getCreateSequenceString(String sequenceName) { return "create sequence " + sequenceName; } @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName; } @Override public String getLimitString(String sql, boolean hasOffset) { return new StringBuffer(sql.length() + 20).append(sql).append(hasOffset ? " limit ? offset ?" : " limit ?").toString(); } @Override public boolean bindLimitParametersInReverseOrder() { return true; } @Override public boolean supportsLimitOffset() { return true; } @Override public boolean supportsVariableLimit() { return false; } @Override public String getQuerySequencesString() { return null; } @Override public String getTableTypeString() { return " engine=sqlite"; } @Override public boolean supportsIfExistsBeforeTableName() { return true; } @Override public boolean supportsColumnCheck() { return false; } @Override public boolean supportsPartitionBy() { return false; } @Override public boolean supportsNoColumnsInsert() { return true; } @Override public boolean supportsCascadeDelete() { return false; } @Override public String getForUpdateString() { return " for update"; } @Override public String getWriteLockString(int timeout) { return " for update"; } @Override public String getReadLockString(int timeout) { return " lock in share mode"; } @Override public String getReadLockString() { return " lock in share mode"; } @Override public boolean supportsOuterJoinForUpdate() { return false; } @Override public boolean supportsIfExistsAfterTableName() { return false; } @Override public boolean supportsTupleDistinctCounts() { return false; } @Override public boolean supportsValuesList() { return true; } @Override public boolean supportsRowValueConstructorSyntax() { return true; } @Override public boolean supportsRowValueConstructorSyntaxInInList() { return true; } @Override public boolean useFollowOnLocking() { return false; } @Override public String getSelectClauseNullString(int sqlType) { return "null"; } @Override public boolean supportsUnionAll() { return true; } @Override public boolean supportsCommentOn() { return false; } @Override public boolean supportsTemporaryTables() { return true; } @Override public String getCreateTemporaryTableString() { return "create temporary table"; } @Override public String getCreateTemporaryTablePostfix() { return ""; } @Override public boolean dropTemporaryTableAfterUse() { return true; } @Override public boolean supportsCurrentTimestampSelection() { return true; } @Override public boolean isCurrentTimestampSelectStringCallable() { return false; } @Override public String getCurrentTimestampSelectString() { return "select current_timestamp"; } @Override public boolean supportsUnion() { return true; } @Override public boolean supportsCommentOnTable() { return false; } @Override public boolean supportsIfExistsBeforeConstraintName() { return false; } @Override public boolean supportsNotNullUnique() { return true; } @Override public boolean supportsExistsInSelect() { return true; } @Override public boolean supportsLobValueChangePropogation() { return false; } @Override public boolean supportsSubqueryOnMutatingTable() { return false; } @Override public String getSelectGUIDString() { return "select hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-4' || substr(hex(randomblob(2)),2) || '-a' || substr(hex(randomblob(2)),2) || '-' || hex(randomblob(6))"; } @Override public boolean supportsLockTimeouts() { return false; } @Override public String getForUpdateNowaitString() { return getForUpdateString(); } @Override public boolean supportsTupleDistinctCountsMultiDimensionalArray() { return false; } @Override public boolean supportsTuplesInSubqueries() { return true; } @Override public boolean supportsSubqueryOnMutatingTableBelow() { return false; } @Override public boolean supportsSubqueryOnMutatingTableAbove() { return false; } @Override public boolean supportsCircularCascadeDeleteConstraints() { return false; } @Override public boolean supportsEmptyInList() { return true; } @Override public boolean supportsExpectedLobUsagePattern() { return false; } @Override public boolean supportsParameterizedInList() { return true; } @Override public boolean requiresCastingOfParametersInSelectClause() { return true; } @Override public boolean supportsRowValueConstructorSyntaxInUpdate() { return true; } @Override public boolean supportsSkipLocked() { return false; } @Override public boolean supportsNoWait() { return false; } @Override public boolean supportsIgnore() { return false; } @Override public boolean supportsValuesClause() { return true; } @Override public boolean supportsWindowFunctions() { return false; } @Override public boolean supportsRowValueConstructorSyntaxWhenDerived() { return true; } @Override public boolean supportsNationalizedTypes() { return false; } @Override public boolean supportsJdbcConnectionLobCreation() { return false; } @Override public String getResultSetWithHoldabilitySuffix(String sql) { return sql; } @Override public String getCreateTableString() { return "create table if not exists"; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } @Override public boolean supportsLockTimeouts() { return false; } } ``` 在这个类中,我们重写了 SQLite 的一些方法,以启用 SQLCipher 扩展。其中,`CIPHER_ALGORITHM` 是 SQLCipher 的加密算法,这里设置为 256。 3. 加密 SQLite 数据库 在运行时,Spring Boot 会自动创建 SQLite 数据库,并使用 SQLCipher 进行加密。如果需要在已有的 SQLite 数据库上启用加密,可以使用下面的代码: ```java import net.sqlcipher.database.SQLiteDatabase; public class SQLiteEncryption { public static void main(String[] args) { SQLiteDatabase.loadLibs(); String databasePath = "/path/to/database.db"; String password = "password"; SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databasePath, password, null); // execute SQL statements here database.close(); } } ``` 其中,`loadLibs` 方法会加载 SQLCipher 库,`openOrCreateDatabase` 方法会打开或创建一个 SQLite 数据库,并使用指定的密码进行加密。在这个方法中,可以执行 SQL 语句等操作。最后,需要关闭数据库连接。 4. 测试 SQLCipher 加密功能 可以使用以下代码测试 SQLCipher 加密功能: ```java import net.sqlcipher.Cursor; import net.sqlcipher.database.SQLiteDatabase; public class SQLiteEncryption { public static void main(String[] args) { SQLiteDatabase.loadLibs(); String databasePath = "/path/to/database.db"; String password = "password"; SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databasePath, password, null); // execute SQL statements here database.execSQL("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)"); database.execSQL("INSERT INTO users (name, email) VALUES (?, ?)", new Object[]{"John Doe", "john.doe@example.com"}); Cursor cursor = database.rawQuery("SELECT * FROM users", new String[]{}); while (cursor.moveToNext()) { int id = cursor.getInt(0); String name = cursor.getString(1); String email = cursor.getString(2); System.out.println(id + "\t" + name + "\t" + email); } cursor.close(); database.close(); } } ``` 这个代码会创建一个名为 `users` 的表,插入一条数据,并查询所有数据并输出。如果一切正常,应该能够顺利执行,并输出查询结果。 注意:在使用 SQLCipher 时,需要使用 `net.sqlcipher.database.SQLiteDatabase` 和 `net.sqlcipher.Cursor` 类替换原来的 `android.database.sqlite.SQLiteDatabase` 和 `android.database.Cursor` 类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值