Files
tripz-llc/docs/16-encryption.md
T
HamzaandClaude Opus 4.8 f3383c3cf8 feat(security): field encryption AES-256-GCM + random IV (at-rest)
- common/crypto/crypto.util.ts: encrypt/decrypt (GCM, random 96-bit IV), format v1:base64(iv|tag|ct)
- EncryptedTransformer applied to users.name + drivers.vehicle_plate (auto, no service change)
- blindIndex (HMAC) helper for future searchable-field encryption (phone)
- tolerant decrypt for legacy plaintext → no migration needed (varchar holds base64)
- ENCRYPTION_KEY env + boot warning if unset; docs/16-encryption.md
- fixes Siro's documented CBC+fixed-IV flaw

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 19:24:27 +03:00

2.7 KiB

16 — التشفير (معيار at-rest)

تصحيح لخطأ سيرو الموثّق (CBC بـ IV ثابت). المعيار عندنا: AES-256-GCM + IV عشوائي لكل قيمة.

المعيار

  • الخوارزمية: AES-256-GCM (تشفير موثَّق authenticated — يكشف أي عبث).
  • IV: عشوائي 96-بت لكل عملية (randomBytes(12)) — لا IV ثابت إطلاقاً.
  • صيغة التخزين: v1:base64(iv | authTag | ciphertext) — الإصدار في المقدمة للترقية المستقبلية.
  • المفتاح: ENCRYPTION_KEY (32 بايت hex؛ openssl rand -hex 32). إلزامي للإنتاج؛ بدونه مفتاح تطوير غير آمن + تحذير عند الإقلاع.
  • الكود: common/crypto/crypto.util.ts — encrypt / decrypt / blindIndex / EncryptedTransformer.

كيف يُطبَّق (بلا تعقيد)

عبر TypeORM transformer على العمود: يشفّر عند الكتابة ويفكّ عند القراءة تلقائياً. لا يتغير منطق الخدمات ولا استجابات الـ API (تظهر مفكوكة).

@Column({ type: 'varchar', nullable: true, transformer: EncryptedTransformer })
name: string;

المطبّق حالياً

  • users.name · drivers.vehicle_plate.

الحقول القابلة للبحث (مثل الهاتف) — الحل الصحيح

تشفير GCM عشوائي يمنع المطابقة بالتساوي (كل تشفير مختلف). للبحث نستخدم فهرس أعمى (blind index): عمود إضافي = HMAC-SHA256(القيمة) حتمي للبحث + العمود المشفّر للتخزين. مخطّط عند بناء بحث الهاتف/الهوية.

الميغريشن (صحيح ومتوافق)

  • لا تغيير مخطّط: الأعمدة varchar تتّسع للنص المشفّر (base64). لا هجرة لازمة لتحويل النوع.
  • تسامح انتقالي: decrypt يُرجع النص القديم غير المشفّر كما هو (يبدأ بلا v1:) — فلا تنكسر القراءة على بيانات قديمة؛ والكتابة الجديدة تُشفّر.
  • عند نقل بيانات حقيقية من سيرو: تُقرأ مفكوكةً من سيرو ثم تُكتب فتُشفَّر عندنا تلقائياً.

ما يُشفَّر مستقبلاً

وثائق السائق وأرقام الهوية/الرخصة (وحدة الوثائق)، ووجهات السحب الحساسة، وأي PII يُضاف — بنفس المحوّل.

← يُقرأ مع: 14-server-conventions · 08-data-model