- 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>
2.7 KiB
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