如何在Java中加密解密SQLite3数据库?(使用sqlite3-jdbc-3.30.1)
实现SQLite3数据库按需加密/解密的方案
针对你的需求,我整理了一套可行的实现方案,帮你完成SQLite数据库的按需加密/解密——也就是仅在需要连接操作时解密,操作完成后自动回到加密状态,具体步骤如下:
一、更换支持加密的JDBC驱动
原生SQLite和你当前用的sqlite3-jdbc-3.30.1本身不支持加密,所以需要替换为支持加密的JDBC驱动。推荐使用sqlite-jdbc-cipher(基于SQLCipher实现),它和原生sqlite-jdbc的API完全兼容,改动成本极低。
你只需要把原有的sqlite3-jdbc-3.30.1.jar替换为对应版本的sqlite-jdbc-cipher jar包即可。
二、修改JDBC连接代码,实现按需解密
核心思路是:只有在需要建立数据库连接时,才提供加密密钥解密数据库;连接关闭后,数据库文件自动恢复加密状态,这样就实现了“仅在需要时解密”的需求。
修改后的代码示例如下:
Connection conn = null; try { // 加载加密驱动(类名和原生sqlite-jdbc一致,无需额外改动) Class.forName("org.sqlite.JDBC"); // 数据库文件路径不变,通过Properties传入加密密钥 String dbUrl = "jdbc:sqlite:C:\\sqlite databases\\library.db"; Properties dbProps = new Properties(); // 这里替换为你自己的强加密密钥,建议不要硬编码,可从环境变量/加密配置文件读取 dbProps.setProperty("key", "your_secure_encryption_key"); // 建立连接时自动解密数据库 conn = DriverManager.getConnection(dbUrl, dbProps); // 在这里执行你的数据库操作(查询、插入、更新等) // 示例:查询字符串数据 String querySql = "SELECT ID, lemma, definition FROM your_table_name"; try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(querySql)) { while (rs.next()) { System.out.printf("ID: %d, Lemma: %s, Definition: %s%n", rs.getInt("ID"), rs.getString("lemma"), rs.getString("definition")); } } } catch (ClassNotFoundException | SQLException exc) { exc.printStackTrace(); } finally { // 关闭连接后,数据库自动回到加密状态 if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
关键补充:
如果你的数据库原本是未加密的,需要先执行一次加密操作,把现有数据库转为加密状态(仅需执行一次):
// 将未加密数据库加密为指定密钥的状态 conn.createStatement().execute("PRAGMA rekey = 'your_secure_encryption_key'");
三、用DB Browser for SQLite操作加密数据库
DB Browser for SQLite原生支持SQLCipher加密的数据库,操作步骤很简单:
- 打开DB Browser,点击「打开数据库」,选择你的
library.db文件 - 在弹出的「SQLCipher加密」窗口中,输入你的加密密钥,选择对应的加密版本(建议选SQLCipher v4,和最新的sqlite-jdbc-cipher兼容)
- 点击「确定」后,就可以正常查看、编辑数据库内容;关闭DB Browser后,数据库文件依然保持加密状态
四、额外注意事项
- 密钥保管:加密密钥是恢复数据的唯一凭证,一旦丢失,数据将无法找回,务必妥善保管(建议通过环境变量、加密配置文件或密钥管理服务获取,不要硬编码在代码里)。
- 版本兼容:确保sqlite-jdbc-cipher的版本和DB Browser支持的SQLCipher版本匹配,避免出现无法打开数据库的情况。
- 性能影响:加密解密会带来轻微的性能开销,但对于以字符串数据为主的数据库,这个影响基本可以忽略。
内容的提问来源于stack exchange,提问作者user9106726




