SQLITE数据库加密

LiteSync带有SQLite数据库加密以及节点之间的通信

可用的密码有ChaCha(在小型设备上比AES快)和XRC4(RC4的扩展版本),甚至比ChaCha还要快。

要打开加密的数据库,我们使用URI参数cipherkeyhexkey。例:

"file:/path/to/file.db?cipher=...&key=..."

或者

"file:/path/to/file.db?cipher=...&hexkey=..."


CIPHER参数

cipher参数可以设置为以下值:

xrc4 - 最快
chacha8 - 快速
chacha12 - 中等
chacha20 - 最强



KEY参数

使用XRC4密钥最多可以为256个字节。例:

"file:data.db?cipher=xrc4&key=testing"

使用ChaCha密钥必须为32个字节长。例:

"file:data.db?cipher=chacha20&key=ThisIsAReallyLongKeyWith32Bytess"

密钥也可以使用十六进制格式的hexkey参数:

"file:data.db?cipher=...&hexkey=11223344556677889900AABBCCDDEEFF..."


创建加密的数据库

使用上面的URI打开数据库,然后创建表并填充它们。



转换现有数据库

当前,不可能直接转换现有数据库。我们必须使用SQLite Shell创建一个加密的数据库,然后将数据从普通数据库复制到该数据库。

只需一步即可完成:

sqlite3 plain.db .dump | sqlite3 "file:encrypted.db?cipher=...&key=..."

如果要检查生成的SQL命令,则分两步进行:

sqlite3 plain.db .dump > out.sql

sqlite3 "file:encrypted.db?cipher=...&key=..." < out.sql

如果要使用与默认页面大小不同的页面大小,请打开生成的out.sql文件,并在顶部添加编译指示行:

PRAGMA page_size=...;

注意:此加密的数据库文件应仅在主节点上使用。建立连接后,副节点将从主节点下载此文件。



数据库头

SQLite数据库的前100个字节构成标题。大多数是固定数据。

在加密中,如果我们拥有已知的纯数据,这将帮助攻击者尝试发现加密密钥。

因此,默认情况下,数据库头不进行加密,但是共有3个选项:


1.不加密数据库头

这是默认设置


2.不要加密数据库标头并使用自定义标头字符串

标头的前16个字节构成标头字符串。默认的标题字符串是“ SQLite格式3”(带有空终止符)。

如果由于某种原因您不想弄清楚该文件是SQLite数据库,则可以更改此字符串。

要启用自定义标头,请使用以下方法编译LiteSync:

CODEC_USE_CUSTOM_HEADER

CODEC_CUSTOM_HEADER="ExampleNewHeader"

自定义标头字符串必须为15或16个字节长。如果使用15个字节,则最后一个将为空终止符。


3.加密数据库头,但不加密其中的字节16-23

SQLite要求对这些字节进行解密。

要加密数据库头,请使用以下方法编译LiteSync:

CODEC_ENCRYPT_DB_HEADER



内部设计

每个页面均按需加密和解密,并且每个页面都有自己的初始化向量(即刻)。每次保存页面时,都会使用新的IV,然后整个加密的页面数据将与以前不同。

WAL页面也会被加密。

节点之间的通信使用数据库选择的相同密码和密钥。每个消息使用不同的初始化向量,因此相同的纯数据作为不同的加密流发送。