SQLiteデータベース暗号化

LiteSyncには、SQLiteデータベースの暗号化とノード間の通信が付属しています

使用可能な暗号は、小型デバイスのAESよりも高速なChaChaと、ChaChaよりもさらに高速なRC4の拡張バージョンであるXRC4です。

暗号化されたデータベースを開くには、URIパラメーターのcipherおよびkeyまたはhexkeyを使用します。例:

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

または

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


サイファー

cipher引数は、次のいずれかの値に設定できます:

xrc4 - 最速
chacha8 - 高速
chacha12 - 中
chacha20 - 最強



キー

XRC4を使用する場合、キーは最大256バイトです。例:

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

ChaChaを使用する場合、キーの長さは32バイトである必要があります。例:

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

hexkeyパラメータを使用して、鍵を16進形式にすることもできます。

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


暗号化されたデータベースの作成

上記のようなURIでデータベースを開き、テーブルを作成してデータを入力します。



既存のデータベースの変換

現在、既存のデータベースを直接変換することはできません。 SQLiteシェルを使用して暗号化データベースを作成し、プレーンデータベースからデータベースにデータをコピーする必要があります。

これは、たった1つのステップで実行できます:

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

または、生成されたSQLコマンドを検査する場合は、2つのステップで:

sqlite3 plain.db .dump > out.sql

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

デフォルトとは異なるページサイズを使用する場合は、生成されたout.sqlファイルを開き、上部にプラグマ行を追加します:

PRAGMA page_size=...;

注意:この暗号化されたデータベースファイルは、プライマリノードでのみ使用してください。接続が確立されると、セカンダリノードはプライマリノードからこのファイルをダウンロードします。



データベースヘッダー

SQLiteデータベースの最初の100バイトがヘッダーを形成します。そのほとんどは固定データです。

暗号化では、既知のプレーンデータがある場合、これは攻撃者が暗号化キーを発見するのに役立ちます。

このため、データベースヘッダーはデフォルトでは暗号化されていませんが、次の3つのオプションがあります:


1. dbヘッダーを暗号化しない

これはデフォルトの動作です


2. dbヘッダーを暗号化せず、カスタムヘッダー文字列を使用します

ヘッダーの最初の16バイトは、ヘッダー文字列を形成します。デフォルトのヘッダー文字列は「SQLite形式3」です(ヌルターミネーター付き)。

何らかの理由でファイルがSQLiteデータベースであることを明確にしたくない場合は、この文字列を変更できます。

カスタムヘッダーの使用を有効にするには、LiteSyncを次のようにコンパイルします:

CODEC_USE_CUSTOM_HEADER

CODEC_CUSTOM_HEADER="ExampleNewHeader"

カスタムヘッダー文字列は15または16バイトの長さである必要があります。 15バイトを使用する場合、最後のバイトはヌルターミネーターになります。


3. dbヘッダーを暗号化しますが、そこから16〜23バイトを暗号化しません

暗号化されなくないようにこれらのバイトはSQLiteで必要です。

データベースヘッダーを暗号化するには、LiteSyncを次のようにコンパイルします:

CODEC_ENCRYPT_DB_HEADER



内部設計

各ページはオンデマンドで暗号化および復号化され、各ページには独自の初期化ベクトル(ノンス)があります。ページが保存されるたびに新しいIVが使用され、暗号化されたページデータ全体が以前とは異なります。

WALページも暗号化されます。

ノード間の通信は、データベース用に選択された同じ暗号とキーを使用します。各メッセージは異なる初期化ベクトルを使用するため、同じプレーンデータが異なる暗号化ストリームとして送信されます。