تحتوي نسخة احتياطية مُستعادة على سجل JSON مشفّر خاص بالمستخدم user-1842؛ ومع ذلك، يقبل التطبيق هذا السجل بعد أن يقوم مهاجم بتعديل البايتات (bytes) المخزنة، مما يؤدي إلى تحول قيمة role (الدور) المستعادة إلى admin (مسؤول). لم يكن المهاجم بحاجة إلى مفتاح التشفير أو إلى صلاحية الوصول إلى واجهة برمجة التطبيقات (API)؛ بل كان بحاجة فقط إلى صلاحية الكتابة في نسخة قاعدة البيانات الاحتياطية أو بياناتها الوصفية (metadata). يتمثل النظام قيد التشغيل لدينا في وحدة برمجية بلغة Python تتولى حماية هذا السجل —الذي يضم الحقول id وemail وrole وcreated_at— أثناء انتقاله بين العميل (client) وواجهة برمجة التطبيقات وقاعدة البيانات والنسخة الاحتياطية. يعتمد التشفير المتماثل على استخدام نفس المفتاح السري لتحويل النص الصريح (plaintext) إلى نص مشفّر (ciphertext) واستعادة النص الصريح لاحقاً. ورغم أن هذه العملية تخفي السجل، إلا أن مجرد الإخفاء لا يضفي الموثوقية على البايتات التي تم تعديلها.
وبناءً على ذلك، فإن السؤال الذي يواجه المدافع يتجاوز مجرد البحث عن خوارزمية التشفير ذات الاسم الأقوى. فعند استرجاع القيمة role=admin من التخزين، كيف يمكن لواجهة برمجة التطبيقات إثبات أن هذه البايتات وسياق السجل المرتبط بها هي بالضبط تلك التي تمت حمايتها في الأصل؟ توضح الحدود الفاصلة الخاصة بالمستخدم user-1842 النقاط التي يجب أن يتوقف عندها النص الصريح، والمواضع التي يجب أن يظل فيها المفتاح منفصلاً، والمواضع التي يمكن للمهاجم فيها تعديل النص المشفّر دون الاطلاع على محتوياته. لنقم بتتبع مسار السجل عبر هذه الحدود:
يوضح هذا الرسم التخطيطي أن قاعدة البيانات والنسخة الاحتياطية تتطلب النص المشفر (ciphertext)، وقيمة فريدة تُستخدم لمرة واحدة (nonce)، وبيانات وصفية مختارة، ولكنها لا تحتاج مطلقاً إلى مفتاح التشفير. القيمة الفريدة (nonce) هي قيمة تُستخدم مرة واحدة مع مفتاح معين لضمان عدم إعادة استخدام نفس المدخلات التشفيرية في عمليات الحماية المتكررة. يمكن تخزين هذه القيمة بجوار النص المشفر؛ إذ أن السرية ليست من وظائفها. في المقابل، يجب أن يظل المفتاح سرياً وأن يتم الحصول عليه من إعدادات التطبيق المحمية، وليس من السجل أو النسخة الاحتياطية.
نظراً لأن المهاجم يمكنه تعديل البايتات المخزنة، فإن عقد السجل يتطلب توفير السرية والسلامة معاً. تقوم التشفير الموثق (Authenticated encryption) بتشفير بايتات JSON والتحقق من عدم تغير تلك البايتات أو السياق المحدد قبل إرجاع النص الصريح (plaintext). بالنسبة للمستخدم user-1842 على سبيل المثال، ستقوم واجهة برمجة التطبيقات (API) بتوثيق user_id=user-1842 و schema_version=1 باعتبارها بيانات مرتبطة (associated data)؛ وهي بيانات وصفية تخضع للتحقق أثناء العملية التشفيرية ولكنها تظل غير مشفرة. وبذلك، لا يمكن إعادة تصنيف نص مشفر منسوخ سراً ليصبح سجلاً لمستخدم آخر، كما لا يمكن تغيير قيمة المخطط (schema) دون التسبب في فشل عملية التحقق.
يكشف النص الصريح عن البريد الإلكتروني والدور (role) بشكل مباشر. يمكن لنمطي AES-CTR و AES-CBC إخفاء هذه الحقول، لكن أياً منهما لا يرفض التعديل بشكل مستقل. يوفر نمط AES-GCM عقد التشفير الموثق المطلوب عند استخدامه مع قيمة فريدة (nonce) جديدة لكل عملية تشفير تحت مفتاح واحد. هل يمكن لنمط التشفير فقط (encryption-only mode) اكتشاف تغير بايت في النسخة الاحتياطية قبل أن تقوم واجهة برمجة التطبيقات بتحليل حقل role؟ تقارن القائمة التالية بين خيارات التخزين المختلفة في ضوء هذا المطلب:
تجعل هذه المقارنة قرار التصميم ملموساً. يرفض خوارزم AES-GCM أي نص مشفر أو قيمة nonce أو مفتاح أو بيانات مرتبطة (associated data) تم تعديلها، ويُصدر خطأً في المصادقة، في حين أن الخيارات التي تقتصر على السرية (confidentiality-only) تترك التطبيق دون هذا الإثبات. لا يعالج AES-GCM مشكلة إعادة استخدام قيمة nonce؛ إذ تؤدي إعادة استخدام قيمة nonce نفسها مع المفتاح ذاته إلى تقويض الأمان، ولذا يجب أن تتم عملية توليد قيمة nonce داخل مسار الحماية بدلاً من أن تكون بيانات وصفية (metadata) يوفرها المستدعي (caller).
قاعدة السجل قم بتخزين قيمة nonce والنص المشفر والبيانات المرتبطة مع السجل. قم بتخزين مفتاح AES بشكل منفصل واحرص على أن تكون كل قيمة nonce فريدة لكل مفتاح.
بعد تحديد آلية العمل (العقد البرمجي)، يمكن للوحدة البرمجية حماية السجل user-1842 دون كشف سجل تم التحقق منه جزئياً للمستدعي. يُنتج مُسلسِل JSON (JSON serializer) بايتات لأن الدالة AESGCM.encrypt تعمل على البايتات. تقوم الوحدة بتوليد مفتاح AES بحجم 256 بت لهذا المثال، وإنشاء قيمة nonce جديدة بحجم 12 بايت، وتخزين حزمة بالصيغة {nonce, ciphertext, ad}. عند النشر الفعلي (deployment)، تنتقل عمليات توليد المفاتيح وحفظها إلى نطاق إدارة المفاتيح المعتمد في التطبيق، بينما تظل حزمة السجل آمنة للتخزين في قاعدة البيانات والنسخ الاحتياطي.
فيما يلي أصغر مسار متكامل للحماية والاستعادة: