Encriptação do Banco de Dados SQLite

O LiteSync vem com encriptação do bancos de dados SQLite bem como da comunicação entre os nós

As cifras disponíveis são a ChaCha, que é mais rápida que a AES em dispositivos de menor capacidade, e a XRC4, uma versão extendida da RC4, ainda mais rápida que a ChaCha.

Para abrir um banco de dados criptografado, utilizamos os parâmetros URI cipher e key (ou hexkey). Exemplo:

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

Or

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


A CIFRA

O argumento cipher pode ser definido com um dos valores a seguir:

xrc4 - mais rápido
chacha8 - rápido
chacha12 - médio
chacha20 - mais forte



A CHAVE

Utilizando a cifra XRC4, a chave pode conter até 256 bytes. Exemplo:

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

Utilizando a cifra ChaCha, a chave precisa ter 32 bytes de tamanho. Exemplo:

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

A chave pode ser definida também em formato hexadecimal, utilizando o parâmetro hexkey:

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


CRIANDO UM BANCO DE DADOS CRIPTOGRAFADO

Abra o banco de dados com uma URI como as apresentadas acima para então criar as tabelas e preenchê-las.



CONVERTENDO UM BANCO DE DADOS EXISTENTE

Atualmente não é possível fazer uma conversão direta de um banco de dados existente. Precisamos criar um banco de dados criptografado utilizando o shell SQLite e então copiar os dados do banco de dados original para o criptografado.

Isso pode ser feito em apenas um passo:

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

Ou em 2 passos, se você quiser inspecionar os comandos SQL gerados:

sqlite3 plain.db .dump > out.sql

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

Se você quiser utilizar um tamanho de página diferente do padrão, abra o arquivo out.sql gerado e adicione a linha pragma no topo:

PRAGMA page_size=...;

Atenção: Esse arquivo de banco de dados criptografado deve ser utilizado apenas em nós primários. Os nós secundários baixarão esse arquivo do nó primário quando a conexão for estabelecida.



CABEÇALHO DO BANCO DE DADOS

Os primeiros 100 bytes de um banco de dados SQLite formam o cabeçalho. A maior parte é de dados fixos.

Na criptografia, um dado aberto conhecido ajuda um agressor nas tentativas de descobrir a chave de encriptação.

Por esse motivo, o cabeçalho do banco de dados não é criptografado por padrão, mas você tem 3 opções neste caso:


1. Não criptografar o cabeçalho do banco de dados

Esse é o comportamento padrão


2. Não criptografar o cabeçalho do banco de dados e utilizar uma string de cabeçalho personalizada

Os primeiros 16 bytes do cabeçalho formam a string de cabeçalho. A string de cabeçalho padrão é "SQLite format 3" (com terminação em caractere nulo).

Se, por alguma razão, você não quiser deixar claro que o arquivo é um banco de dados SQLite, você pode alterar essa string.

Para habilitar o uso de um cabeçalho personalizado, compile o LiteSync com:

CODEC_USE_CUSTOM_HEADER

CODEC_CUSTOM_HEADER="ExampleNewHeader"

A string de cabeçalho padrão deve ter entre 15 e 16 bytes de tamanho. Se utilizar 15 bytes, o último byte será uma terminação em caractere nulo.


3. Criptografar o cabeçalho do banco de dados, mas não criptografar os bytes 16-23

Esses bytes são requeridos pelo SQLite para serem descriptografados.

Para criptografar o cabeçalho do banco de dados, compile o LiteSync com:

CODEC_ENCRYPT_DB_HEADER



DESIGN INTERNO

Cada página é criptografada e descriptografada sob demanda, e cada página tem o seu próprio vetor de inicialização (nonce criptográfico). Cada vez que uma página é salva, um novo vetor de inicialização é utilizado e todos os dados criptografados da página serão diferentes.

Páginas WAL também são criptografadas.

A comunicação entre os nós utiliza as mesmas cifra e chave selecionadas para o banco de dados. Cada mensagem utiliza um vetor de inicialização diferente, de modo que cada dado criptografado seja enviado como uma corrente criptográfica diferente.