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.