بث AE-GCM-HKDF AEAD

يحدّد هذا المستند بشكل رسمي الدالة الرياضية التي تمثلها مفاتيح بث AES-GCM-HKDF، والمرمّزة بتنسيق Proto على النحو التالي: type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey.

يستند هذا التشفير بشكل غير دقيق إلى HRRV151. لتحليل الأمان، نشير إلى HS202.

المفتاح والمعلمات

يتم وصف المفاتيح بالأجزاء التالية (جميع الأحجام في هذا المستند بالبايت):

  • \(\mathrm{KeyValue}\)، سلسلة بايت.
  • \(\mathrm{CiphertextSegmentSize} \in \{1, 2, \ldots, 2^{31}-1\}\).
  • \(\mathrm{DerivedKeySize} \in \{16, 32\}\).
  • \(\mathrm{HkdfHashType} \in \{\mathrm{SHA1}, \mathrm{SHA256}, \mathrm{SHA512}\}\).

بالإضافة إلى ذلك، تستوفي المفاتيح الصالحة السمات التالية:

  • \(\mathrm{len}(\mathrm{KeyValue}) \geq \mathrm{DerivedKeySize}\).
  • \(\mathrm{CiphertextSegmentSize} > \mathrm{DerivedKeySize} + 24\) (يساوي ذلك \(\mathrm{len}(\mathrm{Header}) + 16\) كما هو موضّح لاحقًا).

يتم رفض المفاتيح التي تنتهك أيًا من هذه الخصائص بواسطة Tink، إما عند تحليل المفتاح أو عند إنشاء العنصر الأساسي المقابل.

دالة التشفير

لتشفير رسالة \(\mathrm{Msg}\) باستخدام البيانات المرتبطة بها \(\mathrm{AssociatedData}\)، ننشئ عنوانًا، ونقسم الرسالة إلى أقسام، ونشفّر كل مقطع، ثم ننشئ تسلسلاً للأجزاء المشفَّرة.

إنشاء العنوان

فنحن نختار سلسلة عشوائية منتظمة \(\mathrm{Salt}\) من الطول \(\mathrm{DerivedKeySize}\) وسلسلة عشوائية منتظمة \(\mathrm{NoncePrefix}\) بطول 7.

ثم نضبط \(\mathrm{Header} := \mathrm{len}(\mathrm{Header}) \| \mathrm{Salt} \| \mathrm{NoncePrefix}\)، حيث يتم ترميز طول العنوان كبايت واحد. يُرجى العِلم أنّ \(\mathrm{len}(\mathrm{Header}) \in \{24, 40\}\).

بعد ذلك، نستخدم HKDF3 مع دالة التجزئة التي يوفّرها \(\mathrm{HkdfHashType}\) والمدخلات \(\mathrm{ikm} := \mathrm{KeyValue}\)، \(\mathrm{salt} := \mathrm{Salt}\)و \(\mathrm{info} := \mathrm{AssociatedData}\)مع طول الإخراج \(\mathrm{DerivedKeySize}\). نطلق على النتيجة \(\mathrm{DerivedKey}\).

تقسيم الرسالة

سيتم تقسيم الرسالة \(\mathrm{Msg}\) إلى أجزاء: \(\mathrm{Msg} = M_0 \| M_1 \| \cdots \| M_{n-1}\).

وتم اختيار طولها لتلبية:

  • \(\mathrm{len}(M_0) \in \{0,\ldots, \mathrm{CiphertextSegmentSize} - \mathrm{len}(\mathrm{Header}) - \mathrm{16}\}\).
  • إذا \(n>1\)، ثم \(\mathrm{len}(M_1), \ldots, \mathrm{len}(M_{n-1}) \in \{1,\ldots, \mathrm{CiphertextSegmentSize} - \mathrm{16}\}\).
  • إذا كانت قيمة \(n>1\)، \(\mathrm{len}(M_{0}), \ldots, \mathrm{len}(M_{n-2})\) يجب أن تتضمّن الحد الأقصى للطول وفقًا لما سبق وفقًا للقيود.

\(n\) قد يكون الحد الأقصى \(2^{32}\). وإلا، سيتعذّر التشفير.

تشفير الوحدات

لتشفير شريحة \(M_i\)، يتم احتساب \(\mathrm{IV}_i := \mathrm{NoncePrefix} \| \mathrm{i} \| b\)، حيث تكون \(\mathrm{i}\) هي 4 بايت بترميز واسع النطاق والبايت $b$ يساوي 0x00 إذا كانت $i < n-1$ و0x01 بخلاف ذلك.

ثم نقوم بالتشفير \(M_i\) باستخدام AES-GCM4، حيث يكون المفتاح هو\(\mathrm{DerivedKey}\)، ومتجه التهيئة هو \(\mathrm{IV}_i\)، والبيانات المرتبطة هي السلسلة الفارغة. \(C_i\) هي نتيجة هذا التشفير (أي تسلسل \(C\) و \(T\) في القسم 5.2.1.2 من مرجع AES-GCM المرتبط).

إنشاء سلسلة للأجزاء المشفّرة

وأخيرًا، يتم إجراء تسلسل لكل المقاطع على النحو \(\mathrm{Header} \| C_0 \| \cdots \| C_{n-1}\)، وهو النص المشفر النهائي.

فك التشفير

يعمل فك التشفير على عكس التشفير. ونستخدم العنوان للحصول على\(\mathrm{NoncePrefix}\)وفك تشفير كل مقطع من النص المُشفر على حدة.

قد تسمح واجهات برمجة التطبيقات (وعادةً ما تسمح بذلك) بالوصول العشوائي أو الوصول إلى بداية الملف بدون فحص نهاية الملف. وهذا مقصود، لأنّه من الممكن فك تشفير \(M_i\) من \(C_i\)، بدون فك تشفير جميع مجموعات النص المُشفر السابقة والمتبقية.

ومع ذلك، يجب أن تحرص واجهات برمجة التطبيقات على عدم السماح للمستخدمين بالخلط بين أخطاء نهاية الملف وأخطاء فك التشفير: وفي كلتا الحالتين، من المحتمل أن تعرض واجهة برمجة التطبيقات خطأً، وقد يؤدي تجاهل الاختلاف إلى قدرة الخصم على اقتطاع الملفات بشكل فعّال.

تسلسل المفاتيح وتحليلها

لإنشاء تسلسل لمفتاح بتنسيق "Tink Proto"، نربط أولاً المعلمات بالطريقة الواضحة بالنموذج الأوّلي المقدَّم في aes_gcm_hkdf_streaming.proto. يجب ضبط الحقل version على 0. بعد ذلك، يتم إنشاء تسلسل لهذا باستخدام تسلسل أولي عادي، وتضمين السلسلة الناتجة في قيمة حقل نموذج KeyData. نُعيِّن الحقل type_url على type.googleapis.com/google.crypto.tink.AesGcmHkdfStreamingKey. وقد ضبطنا العلامة key_material_type على SYMMETRIC ونضمّنها في مجموعة مفاتيح. نضبط عادةً قيمة output_prefix_type على RAW. ويستثنى من ذلك أنّه إذا تم تحليل المفتاح مع ضبط قيمة مختلفة لـ output_prefix_type، قد يكتب Tink إما RAW أو القيمة السابقة.

لتحليل مفتاح، نعكس العملية المذكورة أعلاه (بالطريقة المعتادة عند تحليل النماذج الأوّلية). يتم تجاهل الحقل key_material_type. ويمكن تجاهل قيمة output_prefix_type، أو يمكن رفض المفاتيح التي تحتوي على output_prefix_type مختلفة عن RAW. يجب رفض المفاتيح التي تحتوي على قيمة version مختلفة عن 0.

المشاكل المعروفة

ليس من المتوقع أن تكون عمليات تنفيذ وظيفة التشفير المذكورة أعلاه آمنة تمامًا. يُرجى الاطّلاع على سلامة الشوكة.

المراجع


  1. هوانغ، ريهانيتابار، روغاواي، فيزار، 2015. التشفير الذي تمت مصادقته على الإنترنت ومقاومته لإساءة الاستخدام غير القابلة لإعادة الاستخدام مستند CRYPTO 2015. https://eprint.iacr.org/2015/189 

  2. هوانغ، شين، 2020. أمان تشفير البث في مكتبة تينك من Google. https://eprint.iacr.org/2020/1019 

  3. RFC 5869. دالة اشتقاق المفاتيح المستندة إلى بروتوكول HMAC وتوسيع نطاقها (HKDF). https://www.rfc-editor.org/rfc/rfc5869 

  4. معيار NIST SP 800-38D. اقتراح لحظر أوضاع التشفير: Galois/الوضع المضاد (GCM) وGMAC. https://csrc.nist.gov/pubs/sp/800/38/d/final