كيف يعمل التشفير من طرف إلى طرف لدينا
آخر تحديث: يونيو 2026
باختصار
- يتم تشفير بياناتك على جهازك وتترك فقط كنصوص مشفّرة غير قابلة للقراءة. يخزن خادمنا حصريًا Blobs مشفّرة ولا يملك إمكانية الوصول إلى نصوص الكلام الجلي.
- يتم اشتقاق جميع المفاتيح من رمز استرجاع 128-Bit يبقى على جهازك ولا يغادره أبدًا. نحن لا نعرفه ولا يمكننا استعادته.
- يتم تشفير كل سجل على حدة باستخدام مفتاح خاص به وتحقق من صحته قبل فك التشفير (Verify-before-Decrypt مع Ed25519).
- E2EE لا يحمي كل شيء: تبقى بيانات وصفية معينة (كمية البيانات، أوقات الوصول) مرئية، وجهاز مخترق أو رمز استرجاع مفقود لا يمكن إنقاذهما بالتشفير.
ما تعنيه "من طرف إلى طرف" بالنسبة لنا
تشفير من طرف إلى طرف يعني: نص الكلام الجلي لبياناتك موجود فقط على أجهزتك الخاصة. التشفير وفك التشفير يتم حصريًا محليًا. ما يتم مزامنته بين الأجهزة وتخزينه على خادمنا مشفّر بالفعل قبل أن يغادر الجهاز.
بشكل ملموس: يتم ترميز صف من البيانات بطريقة قانونية إلى JSON على العميل ثم يتم تشفيره باستخدام آلية AEAD. يستقبل الخادم فقط Blob بايت معتم بالإضافة إلى بعض حقول الإدارة. هو لا يملك أي من المفاتيح اللازمة لفك التشفير. هذه خاصية معمارية، وليست وعد: بما أن المفاتيح لا تصل أبدًا إلى الخادم، فإن الخادم تقنيًا لا يستطيع قراءة المحتوى.
انقر فوق المكونات للحصول على التفاصيل:
الجهاز أ (المرسل)
يتم تشفير البيانات محليًا على الجهاز باستخدام AES-256-GCM. رمز الاسترداد والمفاتيح المشتقة لا تغادر جهازك أبدًا.
كيف يتم تشفير بياناتك
نستخدم المكونات المثبتة والموحدة من المكتبات @noble/ciphers و @noble/hashes و @noble/curves:
- AES-256-GCM يشفّر سجلاتك. AES-256-GCM هي آلية AEAD تضمن في نفس الوقت السرية (لا أحد يقرأ معك) والنزاهة (التلاعب يظهر). يستخدم كل سجل Nonce عشوائي 12-Byte و رمز مصادقة 16-Byte (MAC). الصيغة: nonce(12) ‖ ciphertext ‖ mac(16).
- XChaCha20-Poly1305 يشفّر المفاتيح أثناء ربط الأجهزة (Key-Wrapping). إنها أيضًا آلية AEAD، لكنها تستخدم Nonce أطول 24-Byte، مما يجعل Nonces العشوائية غير حرجة.
- AAD (Associated Data) يربط كل نص مشفّر ببيانات وصفية - الرأس، Bucket، UUID السجل، المراجعة، Key-Epoch، نسخة المخطط والطول المرفوع. هذه الحقول مصادق عليها معًا: إذا تم تغيير أي منها، فشل فك التشفير. يتم رفض AAD الفارغة بقسوة (حماية Confused-Deputy).
- Padding يخفي الحجم الدقيق: يتم تعبئة كل سجل إلى حجم Bucket (256 أو 1024 أو 4096 أو 16384 أو 65536 بايت؛ وفوق ذلك مضاعفات من 65536). بهذه الطريقة، يكشف حجم Blob فقط فئة تقريبية، وليس كمية البيانات الدقيقة.
- توقيع Ed25519 (blob_sig) يوقع كل Blob. قبل كل فك تشفير، يتحقق العميل من هذا التوقيع مقابل مفاتيح الجهاز المرخصة (Verify-before-Decrypt). يتم التحقق بصرامة RFC-8032 (zip215:false)، وهو ما يستثني التزييف عبر نقاط الترتيب المنخفضة. تؤدي البيانات المعدّلة فورًا إلى خطأ، وليس عيب صامت.
مفاتيحك تبقى على جهازك
جذر كل شيء هو 128-Bit Recovery Entropy - رمز الاسترجاع. من هذه 16 بايت عشوائية يتم اشتقاق Master-Secret بشكل حتمي باستخدام HKDF-SHA256 (دالة اشتقاق مفاتيح تنتج عن السر الكثير من المفاتيح المنفصلة بالمجال) ومنها مفاتيح إضافية: معرّف حساب، Key-Encryption-Key، مفتاح المصادقة (authSeed) ومفتاح التوجيه. يستخدم كل اشتقاق تسمية خاصة به ومُصدّرة (على سبيل المثال mypep/master/v1)، بحيث لا تتداخل المفاتيح.
لكل Collection يوجد مفتاح Collection منفصل، ولكل سجل ومراجعة مفتاح سجل منفصل (rec/<uuid>/<rev>). هذا المفتاح المنفصل لكل (السجل، المراجعة) يوفر فصل مفاتيح كامل: لا يتم استخدام مفتاح AES-GCM أبدًا مرتين - وهي حماية قوية ضد هجمات Nonce-Reuse.
Master-Secret يتم عن قصد عدم تخزينه. محليًا توجد فقط القيم المشتقة ومفاتيح التوقيع/الالتفاف الخاصة بالجهاز - في المتصفح في IndexedDB.
انقر فوق المفتاح للتفاصيل:
رمز الاسترداد
عشوائية 128 بت. مفتاح الجذر المطلق. يتم إنشاؤه أثناء إنشاء الحساب ولا يغادر جهازك أبدًا.
الاسترجاع - ميزة ومسؤولية: شجرة المفاتيح بأكملها تعتمد على رمز الاسترجاع. نحن لا نخزنه؛ يتم استبعاد باب خلفي أو Key-Escrow أو إعادة تعيين من جانب الخادم معماريًا - ليس فقط بالسياسة، بل لأن المفاتيح لا تصل تقنيًا إلى الخادم أبدًا. هذا هو جوهر E2EE الحقيقي: لا أحد سواك - ولا نحن - يمكنه استعادة بياناتك بدون رمز الاسترجاع أو جهاز مقترن. إذا فُقد الرمز ولم يعد هناك جهاز مقترن، تصبح البيانات غير قابلة للوصول إلى الأبد.
ما يراه خادمنا - وما لا يراه
يخزن الخادم فقط Blobs مشفّرة. هو لا يرى: محتوى سجلاتك، أسماء Collections الخاصة بك (تظهر فقط كـ Bucket معتم HMAC-SHA256) أو مفاتيحك.
بصراحة، لكنه يرى بعض البيانات الوصفية: قيم Bucket المعتمة، مراجعات السجلات، فئة الحجم التقريبية عبر Padding، تكرار المزامنة، معرّفات الأجهزة (كـ SHA-256 hash لمفاتيح الجهاز) وموضع Cursor أثناء المزامنة. من هذا يمكن الاستدلال على أن الحساب نشط وتقريبًا كم وحجم البيانات التي يتم نقلها متى - لكن ليس ما يتعلق بها من الناحية المضمونية.
يتم حل التنازعات بحتة عبر المراجعات (المراجعة الأعلى تفوز، "Last-Write-Wins")، لأن الخادم لا يعرف المحتوى ولا يمكنه الدمج المضمون. تتم المصادقة عبر Challenge-Response مع Ed25519 ورمز JWT لاحق؛ يتم توقيع قائمة الجهاز بمفتاح المصادقة الخاص بك والتحقق منه حصريًا على جانب العميل.
أجهزة متعددة (الربط)
يتم ربط جهاز جديد، مثل المتصفح، عبر QR Code مع الهاتف. ينقل QR Code مفاتيح الجهاز العام للمتصفح مباشرة (out-of-band)، وليس عبر الخادم - هذا يحمي تبديل المفاتيح من هجمات Man-in-the-Middle. يقوم الهاتف بتعبئة Identity-Bundle (مفاتيح بيانات الحساب، مفتاح المصادقة، معرّف الحساب، مفتاح التوجيه) عبر X25519-ECDH و XChaCha20-Poly1305 حصريًا للمتصفح ونقله مشفّرًا.
بعد فك التشفير، يعرض المتصفح Fingerprint (SHA-256 لمعرّف الحساب، كمجموعات Hex). إذا تطابق مع العرض على الهاتف، فتم التأكد من أنك استقبلت Bundle الصحيح. عملاء الويب ليس لديهم رمز استرجاع خاص بهم: عند فقدان تخزين المتصفح، ما عليك سوى الربط مرة أخرى مع الهاتف.
خطوات اقتران الأجهزة
يولد المتصفح مفاتيح أجهزة مؤقتة ويعرضها كرمز QR. يقوم الهاتف الذكي بمسحه مباشرة. نظرًا لأن هذا يتم مباشرة عبر الكاميرا (خارج النطاق)، فإن تبادل المفاتيح محصن ضد هجمات رجل في المنتصف.
ما لا يحميه هذا
E2EE قوي، لكنه ليس حلاً سحريًا. صادق بشأن الحدود:
- جهاز مخترق: برامج ضارة في سياق المتصفح أو الوصول المباشر إلى IndexedDB يمكنها قراءة المفاتيح المخزنة محليًا وفك تشفير كل شيء. قاعدة البيانات المحلية موجودة بنص واضح.
- رمز استرجاع مفقود: بدون رمز وبدون جهاز مقترن، لا توجد طريقة للعودة. لا يوجد تدوير مفاتيح ولا آلية نسخ احتياطي.
- البيانات الوصفية: كميات البيانات وفئات الحجم وأنماط الوصول والأوقات تبقى مرئية للخادم.
- Blobs الصور: الصور معنونة بالمحتوى (
blob_id = sha256(blob)). من يملك نص واضح بالفعل يمكنه التحقق من ما إذا تم تحميل هذه الصورة بالضبط. - خادم خبيث: لا يمكنه قراءة أو تزييف المحتوى (Verify-before-Decrypt يحمي)، لكن يمكنه الاحتفاظ بالبيانات أو إعادة تسليم قوائم الأجهزة الموقعة القديمة (Replay). الضرر من Replay كهذا محدود: يتم تسجيل الجهاز بطريقة بوليانية، بحيث لا تستبدل قائمة معادة قديمة الحالة الحالية. لا يمكن للخادم اختراع بيانات صحيحة جديدة.
- مفتاح المصادقة: من يحصل على مفتاح المصادقة يمكنه تغيير قائمة الجهاز وإعادة المصادقة. يجب أن يبقى سريًا.
المكونات التشفيرية في نظرة عامة
- AES-256-GCM — تشفير السجل (AEAD)؛ 12-Byte Nonce، 16-Byte MAC.
- XChaCha20-Poly1305 — Key-Wrapping أثناء الربط (AEAD)؛ 24-Byte Nonce، 16-Byte MAC.
- Argon2id v1.3 — اشتقاق قائم على الكلمة السرية ودائم التخزين (الافتراضي: 64 MiB، 3 تكرارات، 4 Lanes)؛ متاح للوظائف المستقبلية القائمة على الكلمة السرية، لكن ليس لرمز الاسترجاع - يبلغ بالفعل 128 Bit Entropy عشوائي ولا يحتاج إلى صلابة التخزين.
- HKDF-SHA256 — اشتقاق جميع المفاتيح من رمز الاسترجاع، منفصل بالمجال عبر التسميات المرقمة؛ 32-Byte output.
- HMAC-SHA256 — توجيه معتم للـ Collections (حساب Bucket).
- SHA-256 — Hashing للـ Fingerprints ومعرّفات الأجهزة وعنونة الصور.
- Ed25519 (RFC-8032-strikt، zip215:false) — التوقيعات للسجلات وقائمة الجهاز والمصادقة.
- X25519-ECDH — تبديل المفاتيح أثناء ربط الجهاز.
- Padding-Buckets (256 B إلى 65536 B، فوق ذلك مضاعفات من 65536) — تغطية الحجم.
- طول المفتاح 32 Bytes (256 Bit) باستمرار.