Chiffrement de base de données SQLite

LiteSync comes with encryption of SQLite databases as well as the communication between the nodesLiteSync est livré avec le cryptage des bases de données SQLite ainsi que la communication entre les nœuds

Les chiffres disponibles sont ChaCha, qui est plus rapide que AES sur les petits appareils, et XRC4, une version étendue de RC4 encore plus rapide que ChaCha.

Pour ouvrir une base de données cryptée, nous utilisons les paramètres d'URI cipher et key ou hexkey. Exemple :

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

Or

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


LE CIPHER

L'argument cipher peut être défini sur l'une de ces valeurs :

xrc4 - le plus rapide
chacha8 - rapide
chacha12 - moyen
chacha20 - le plus fort



LA CLÉ

En utilisant XRC4, la clé peut contenir jusqu'à 256 octets. Exemple :

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

En utilisant ChaCha, la clé doit être longue de 32 octets. Exemple :

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

La clé peut également être au format hexadécimal, en utilisant le paramètre hexkey :

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


CRÉATION D'UNE BASE DE DONNÉES CRYPTÉE

Ouvrir la base de données avec un URI comme ceux ci-dessus, puis créer les tables et remplissez-les.



CONVERSION D'UNE BASE DE DONNÉES EXISTANTE

Actuellement, il n'est pas possible d'effectuer une conversion directe d'une base de données existante. Nous devons créer une base de données chiffrée à l'aide du shell SQLite, puis y copier les données de la base de données ordinaire.

Cela peut être fait en une seule étape :

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

Ou en 2 étapes si vous voulez inspecter les commandes SQL générées :

sqlite3 plain.db .dump > out.sql

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

Si vous voulez utiliser une taille de page différente de la valeur par défaut, ouvrez le fichier out.sql généré et ajoutez la ligne pragma en haut :

PRAGMA page_size=...;

Attention : Ce fichier de base de données chiffré ne doit être utilisé que sur le nœud principal. Les nœuds secondaires téléchargeront ce fichier à partir du nœud principal lorsque la connexion sera établie.



HEADER DE BASE DE DONNÉES

Les 100 premiers octets d'une base de données SQLite forment l'header. La plupart sont des données fixes.

En cryptage, si nous avons des données simples connues, cela aide un attaquant à essayer de découvrir la clé de cryptage.

Pour cette raison, l'header de la base de données n'est pas chiffré par défaut, mais vous avez un total de 3 options :


1. Pas crypter l'header de la base de données

Ceci est le comportement par défaut


2. Pas crypter l'header de la base de données et utiliser une chaîne d'header personnalisée

Les 16 premiers octets de l'header forment la chaîne d'header. La chaîne d'header par défaut est "SQLite format 3" (avec un terminateur nul).

Si, pour une raison quelconque, vous ne voulez pas indiquer clairement que le fichier est une base de données SQLite, vous pouvez modifier cette chaîne.

Pour activer l'utilisation d'un header personnalisé, compiler LiteSync avec:

CODEC_USE_CUSTOM_HEADER

CODEC_CUSTOM_HEADER="ExampleNewHeader"

La chaîne d'header personnalisée doit être longue de 15 ou 16 octets. Si vous utilisez 15 octets, le dernier sera un terminateur nul.


3. Pas crypter l'header de la base de données mais n'en crypter pas les octets 16-23

Ces octets sont requis par SQLite pour être non chiffrés.

Pour chiffrer l'header de la base de données, compiler LiteSync avec:

CODEC_ENCRYPT_DB_HEADER



DESIGN INTERNE

Chaque page est chiffrée et déchiffrée à la demande, et chaque page a sa propre vecteur (nonce)                       d'initialisation. Chaque fois qu'une page est enregistrée, un nouveau IV est utilisé, puis toutes les données                       de la page cryptée seront différentes qu'auparavant.

Les pages WAL sont également cryptées.

La communication entre les nœuds utilise le même cipher et la même clé sélectionnés pour la base de données. Chaque message utilise un vecteur d'initialisation différent, de sorte que les mêmes données simples sont envoyées sous la forme d'un flux cryptographique différent.