SQLITE数据库加密
LiteSync带有SQLite数据库加密以及节点之间的通信
可用的密码有ChaCha(在小型设备上比AES快)和XRC4(RC4的扩展版本),甚至比ChaCha还要快。
要打开加密的数据库,我们使用URI参数cipher和key或hexkey。例:
"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页面也会被加密。
节点之间的通信使用数据库选择的相同密码和密钥。每个消息使用不同的初始化向量,因此相同的纯数据作为不同的加密流发送。