تشفير قواعد بيانات 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) أن يأخذ أحد القيم االتالية:

xrc4 - الأسرع
chacha8 - سريع
chacha12 - متوسط
chacha20 - الأقوى



المفتاح

باستخدام XRC4، يمكن للمفتاح أن يصل إلى 256Byte. مثال:

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

أما عند استخدام ChaCha فيجب أن يكون طول المفتاح 32Bytes

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

ويمكن أن يكون المفتاح بصيغة سداسي عشرية hexadecimal وذلك يتكون باستخدام الوسيط hexkey :

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


إنشاء قاعدة بيانات مشفرة

قم بإنشاء قاعدة البيانات مستخدماً URI السابقة، ثم قم بإنشاء الجداول ملئها.



تشفير قاعدة بيانات موجودة مسبقاً

لا يوجد طريقة مباشرة لتحويل قاعدة البيانات إلى قاعدة بيانات مشفرة. لكننا نستطيع إنشاء قاعدة بيانات جديدة مشفرة باستخدام SQLite shell ثم نقوم بنسخ بيانات القاعدة القديمة إلى القاعدة المشفرة.

1. يمكن القيام بذلك في خطوة واحدة:

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

2. أو بخطوتين في حال أردنا تفحص أوامر SQL:

sqlite3 plain.db .dump > out.sql

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

إذا أردت تغيير حجم الصفحة المستخدمة افتح ملف out.sql وضع هذا الأمر أعلاه:

PRAGMA page_size=...;

تنويه: يجب استخدام ملف قاعدة البيانات المشفر مع العقدة الأولية فقط. تقوم باقي العقد الثانوية بتحميل هذا الملف من العقدة الأولية عندما يكون الاتصال قائم.



ترويسة قاعدة البيانات

تأتي أول 100 بايت من قاعدة بيانات SQLite من الترويسة حيث يكون معظمها بيانات ثابتة (fixed data)

إذا كان ليدنا بيانات فعلية معروفة، يمكن للمهاجم أن يستخدم هذه البيانات لاكتشاف مفتاح التشفير وفك التشفير.

لذلك لا نقوم بتشفير ترويسة قاعدة البيانات بشكل افتراضي، لكن لديك 3 خيارات:


1. لا تقم بتشفير ترويسة قاعدة البيانات

هذا الخيار الافتراضي


2. لا تقم بتشفير ترويسة قاعدة البيانات وقم باستخدام سلسلة محارف مخصصة في الترويسة

تشكل أول 16 بايت من الترويسة سلسلة محارف الترويسة. إن سلسلة محارف الترويسة الافتراضية هي "SQlite format 3" (وتنتهي بالرمز Null)

إذا لم ترد الإفصاح عن طيبعة الملف(أي أن الملف هوي ملف قاعد بيانات sqlite) يمكن تغيير هذه السلسلة المحرفية

لتفعيل استخدام ترويسة مخصصة قم بترجمة LiteSyync باستخدام الأمر:

CODEC_USE_CUSTOM_HEADER

CODEC_CUSTOM_HEADER="ExampleNewHeader"

يجب أن يكون طول الترويسة المخصصة 15 أو 16 بايت. في حال استخدام 15 بايت، سيكون آخر بايت null terminator.


3. قم بتشفير ترويسة قاعدة البيانات لكن لا تشفّر البايتات 16-23 منها.

إذ أن SQLite بحاجة هذه البايتات ليقوم بالتشفير.

قم بترجمة LiteSync باسخدام الأمر التالي إذا أدرت تشفير ترويسة قاعدة البيانات:

CODEC_ENCRYPT_DB_HEADER



التصميم الداخلي

يتم تشفير وفك تشفير كل صفحة عند الحاجة. حيث يكون لكل صفحة شعاع تهيئة IV خاص بها. في كل مرة يتم فيها حفظ الصفحة، فإنه يتم استخدام شعاع تهيئة جديد وبذلك ستصبح صفحة البيانات المشفرة مختلفة عن الصفحة قبل الحفظ

كما يتم تشفير صفحات WAL.

يستخدم التواصل بين العقد نفس الشيفرة و المفتاح المختارين من أجل قاعدة البيانات. كل رسالة تستخدم شعاع تهيئة مختلف فبذلك يمكن إرسال نفس البيانات عبر مجاري مشفرة مختلفة.