Encrypted SQLite Databases with Python and SQLCipher

本文介绍如何使用SQLCipher为SQLite数据库提供256位AES加密。包括构建SQLCipher库、安装Python绑定pysqlcipher的过程,并演示了如何从Python脚本交互加密的SQLite数据库。

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

原文地址http://charlesleifer.com/blog/encrypted-sqlite-databases-with-python-and-sqlcipher/

photos/p1414470640.98.png

SQLCipher, created by Zetetic, is an open-source library that provides transparent 256-bit AES encryption for your SQLite databases. SQLCipher is used by a large number of organizations, including Nasa, SalesForce, Xerox and more. The project is open-source and BSD licensed. Best of all, there are open-source python bindings.

In this post, I'll show how to get started writing Python scripts that interact with encrypted SQLite databases. For users of the peewee ORM, I will demonstrate the usage of the sqlcipher playhouse module. Finally, I'll show how to convert your existing SQLite databases into encrypted databases suitable for use with SQLCipher.

Building SQLCipher

Let's get started by cloning the most recent version of the SQLCipher library and installing it on our system.

$ git clone https://github.com/sqlcipher/sqlcipher
$ cd sqlcipher

To compile SQLCipher, we will link against OpenSSL's libcrypto, so make sure you have OpenSSL installed before proceeding. I've also specified that we want to enable the full-text search extension. For the adventurous, the SQLite documentation contains a comprehensive list of compile options.

$ ./configure \
  --enable-tempstore=yes \
  CFLAGS="-DSQLITE_HAS_CODEC -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS" \
  LDFLAGS="-lcrypto"

$ make
$ sudo make install

unzip -q sqlcipher-master.zip  
cd sqlcipher-master  
sudo apt install openssl libssl-dev tcl tk sqlite3
./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto"
make
./sqlcipher

You should now be able to fire up the sqlcipher shell, which by default is connected to an in-memory database:

./sqlcipher EnMicroMsg.db
sqlite> PRAGMA key = '1234567';
sqlite> PRAGMA cipher_use_hmac = off;
sqlite> PRAGMA kdf_iter = 4000;
sqlite> ATTACH DATABASE 'wechat.db' AS wechat KEY '';
sqlite> SELECT sqlcipher_export('wechat');
sqlite> DETACH DATABASE wechat;
$ sqlcipher
SQLCipher version 3.8.6 2014-08-15 11:46:33
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>

Kicking the tires on SQLCipher

To create an encrypted database, we can use the SQLCipher shell, specifying a key using a special PRAGMA command:

sqlite> .open testing.db
sqlite> PRAGMA key='testing';
sqlite> create table people (name text primary key);
sqlite> insert into people (name) values ('charlie'), ('huey');
sqlite> .quit

If we take a look at the data in testing.db, we'll find that it is completely garbled:

$ hexdump -C testing.db
0000  04 37 1e 64 12 fb a2 0b  8d 88 2f 72 fd c6 4b e6  |.7.d....../r..K.|
0010  7f 80 14 ec 74 68 83 00  e9 d2 4f 2e 80 5d 05 da  |....th....O..]..|
0020  f0 44 f3 83 23 5e 29 e4  73 fc 29 1b 2d 6a 1d bc  |.D..#^).s.).-j..|
0030  be 94 e6 12 6e 7a 28 32  15 cd 7b 1e a5 3c f7 52  |....nz(2..{..<.R|
0040  1a 51 37 40 28 70 3e fe  5d d9 0f 06 cc 76 4c 98  |.Q7@(p>.]....vL.|
...

If we try to open the database using the normal SQLite client, or if we specify the incorrect key, the data will be unreadable:

$ sqlite3 testing.db
SQLite version 3.8.7 2014-10-17 11:24:17
Enter ".help" for usage hints.
sqlite> .schema
Error: file is encrypted or is not a database
sqlite> .quit

$ sqlcipher testing.db
SQLCipher version 3.8.6 2014-08-15 11:46:33
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> pragma key='wrong';
sqlite> .schema
Error: file is encrypted or is not a database

SQLCipher supports a number of special commands besides PRAGMA key. For the full list, check out the API documentation.

Building pysqlcipher

Run the following commands to install the latest version of pysqlcipher globally on your system:

安装依赖:
sudo apt-get install python-dev
sudo apt-get install sqlite sqlite3
sudo apt-get install libsqlite3-dev
//pip install lxml
//pip install pillow
//pip install pycrypto
//pip install pymongo
//wget no-check-certificate https://bootstrap.pypa.io/ez_setup.py
//sudo apt-get install gcc
sudo apt-get install openssl

sudo apt-get install libssl-dev

git clone https://github.com/leapcode/pysqlcipher/
cd pysqlcipher
执行 python setup.py install 或 pip install pysqlcipher 报如下错误:
/usr/bin/ld: cannot find -lsqlcipher
/usr/bin/ld: cannot find -lsqlcipher
collect2: error: ld returned 1 exit status

error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

原因:The default installation will not link against your system sqlcipher, 
but will link against the downloaded amalgamation.
解决方法:
执行 python setup.py install --bundled   #Build against the system libsqlcipher
$ git clone https://github.com/leapcode/pysqlcipher/
$ cd pysqlcipher
$ python setup.py build_sqlcipher  # Build against the system libsqlcipher
$ sudo python setup.py install

If you are installing into a virtualenv, I would not necessarily recommend installing pysqlcipher using pip, simply because it may fetch the SQLCipher source from a different remote source. The default installation will not link against your system sqlcipher, but will link against the downloaded amalgamation.

To install in a virtualenv and build against the system libsqlcipher, you can clone the source tree into your virtualenv and build there:

$ cd my_env && source bin/activate
$ git clone https://github.com/leapcode/pysqlcipher/
$ cd pysqlcipher
$ python setup.py build_sqlcipher
$ python setup.py install

Connecting to an encrypted database from Python

Let's see how to use SQLCipher from a Python script. pysqlcipher implements the db-api 2.0 spec, so if you've worked with databases in Python before, you'll feel right at home.

>>> from pysqlcipher import dbapi2 as sqlcipher
>>> db = sqlcipher.connect('testing.db')

In order to actually make queries, we need to specify a passphrase using the PRAGMA keystatement. Additionally, we need to specify the key derivation iterations using PRAGMA kdf_iter, which has a default value of 64000.

>>> db.executescript('pragma key="testing"; pragma kdf_iter=64000;')
<pysqlcipher.dbapi2.Cursor object at 0x7f2a77be40a0>
>>> db.execute('select * from people;').fetchall()
[(u'charlie',), (u'heuy',)]

If we attempt to connect with the incorrect passphrase, we will receive a DatabaseError:

>>> db = sqlcipher.connect('testing.db')
>>> db.execute('pragma key="wrong"')
<pysqlcipher.dbapi2.Cursor object at 0x7f167ec2d0a0>
>>> db.execute('select * from people;')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
pysqlcipher.dbapi2.DatabaseError: file is encrypted or is not a database

Encrypting an existing SQLite Database

If, like me, you have some existing SQLite databases you wish to convert over to SQLCipher, the following commands should get you started. These commands, and other examples, can be found in the SQLCipher documentation:

$ sqlcipher plaintext.db
sqlite> ATTACH DATABASE 'encrypted.db' AS encrypted KEY 'my password';
sqlite> SELECT sqlcipher_export('encrypted');
sqlite> DETACH DATABASE encrypted;

That's it! Now encrypted.db will contain an encrypted copy of the data in plaintext.db.

引用:[1] https://github.com/leapcode/pysqlcipher

          [2] 导出安卓微信聊天数据

### SQLiteSQLCipher的关系 SQLite 是一种轻量级的嵌入式关系型数据库引擎,广泛用于移动设备、桌面应用以及服务器端开发中。它以其简单易用的特点而闻名,但由于其设计初衷并未考虑数据的安全性和隐私保护,因此默认情况下,SQLite 数据库中的数据是以明文形式存储的[^2]。 相比之下,SQLCipher 是基于 SQLite 的一个扩展库,旨在为 SQLite 提供强大的加密功能。通过采用 AES-256 加密算法,SQLCipher 能够对整个数据库文件进行透明加密,确保即使数据库文件被非法获取,也无法轻易读取其中的数据内容[^1]。 --- ### SQLiteSQLCipher 的主要区别 | 特性 | SQLite | SQLCipher | |---------------------|---------------------------------------------|--------------------------------------------| | **核心功能** | 基础数据库操作 | 支持基础数据库操作并附加加密功能 | | **数据安全性** | 明文存储,无内置加密机制 | 使用 AES-256 对数据库文件进行加密 | | **性能影响** | 高效运行,几乎无额外开销 | 由于加密/解密过程,可能带来一定性能损耗 | | **适用场景** | 不涉及敏感数据的应用 | 存储敏感信息(如密码、支付记录等) | 尽管两者都属于同一技术体系,但 SQLCipher 更适合那些需要保障数据安全性的应用场景[^3]。 --- ### 如何在项目中集成 SQLiteSQLCipher #### Android 平台上的集成方法 以下是将 SQLCipher 应用于 Android 开发的具体步骤: 1. 添加 Maven 或 Gradle 依赖项 如果您正在构建 Android 项目,则需引入官方支持的 SQLCipher 库: ```gradle dependencies { implementation 'net.zetetic:android-database-sqlcipher:4.5.0' } ``` 2. 替换原生 SQLiteDatabase API 在代码层面,应改用 `SQLiteDatabase` 的替代类——即由 SQLCipher 提供的支持加密版实例化对象的方法。 示例代码如下所示: ```java import net.sqlcipher.database.SQLiteDatabase; import android.content.Context; public class DatabaseHelper extends net.sqlcipher.database.SQLiteOpenHelper { private static final String DATABASE_NAME = "encrypted.db"; private static final int DATABASE_VERSION = 1; public DatabaseHelper(Context context, String passphrase) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.setWriteAheadLoggingEnabled(true); // 可选优化设置 } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS users"); onCreate(db); } public static SQLiteDatabase openDatabase(String path, String password) { return SQLiteDatabase.openOrCreateDatabase(path, password, null); } } ``` 3. 设置加密口令 当首次创建或打开现有数据库时,必须指定有效的加密密钥字符串作为参数传递给构造函数或者静态工厂方法调用处。 #### Spring Boot 中的集成方案 对于 Java 后端服务而言,在 Spring Boot 环境下也可以轻松完成 SQLCipher 的部署工作流程: 1. 引入必要的 JDBC 连接器组件包; ```xml <!-- pom.xml --> <dependency> <groupId>org.xerial</groupId> <artifactId>sqlite-jdbc</artifactId> <version>3.36.0.3</version> </dependency> <dependency> <groupId>net.sf.sqlcipher</groupId> <artifactId>sqlcipher</artifactId> <version>4.4.3</version> </dependency> ``` 2. 自定义 DataSource Bean 定义逻辑;例如下面这段 Kotlin 实现片段展示了如何加载带密码验证机制下的 SQLite 数据源实例: ```kotlin import org.springframework.context.annotation.Bean import org.springframework.jdbc.datasource.DriverManagerDataSource import javax.sql.DataSource fun dataSource(): DataSource { val ds = DriverManagerDataSource() ds.driverClassName = "org.sqlite.JDBC" ds.url = "jdbc:sqlite:path/to/mydb.db?encrypt=true&key=your_password_here" return ds } ``` 以上两种方式分别适用于移动端和后端系统的实际需求情况,并且均能有效利用到 SQLCipher 所带来的增强型安全保障措施[^3]。 --- ### 总结 SQLite 主要关注于提供快速便捷的基础数据库管理能力,而 SQLCipher 则进一步增强了它的功能性范围至包括企业级别的信息安全防护领域之中。无论是针对个人还是商业用途来说,合理选用这两种工具都可以极大地促进软件产品的整体质量水平提升。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值