يحدِّد هذا المستند رسميًا الدالة الحسابية التي تمثّلها مفاتيح البث باستخدام HMACHAES-CTR (المشفَّرة بتنسيق proto على النحو التالي:
type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey
).
يستند هذا التشفير بشكل فضفاض إلى [HRRV15]1. لتحليل
الأمان، يُرجى الرجوع إلى [HS20]2. يُرجى العلم أيضًا أنّ اختبارات Tink المتعددة اللغات
تتضمّن اختبارًا هو
aes_ctr_hmac_streaming_key_test.py الذي
يحتوي على test_manually_created_test_vector
مع دليل إرشادي كامل حول كيفية
الحصول على نص مشفّر.
المفتاح والمَعلمات
يتم وصف المفاتيح من خلال الأجزاء التالية (جميع الأحجام في هذا المستند بالكلمات الثنائية):
- \(\mathrm{InitialKeyMaterial}\)، سلسلة بايت: مادة المفتاح الأولية
- \(\mathrm{CiphertextSegmentSize} \in \{1, 2, \ldots, 2^{31}-1\}\).
- \(\mathrm{DerivedKeySize} \in \{16, 32\}\).
- \(\mathrm{HkdfHashType} \in \{\mathrm{SHA1}, \mathrm{SHA256}, \mathrm{SHA512}\}\).
- \(\mathrm{HmacHashType} \in \{\mathrm{SHA1}, \mathrm{SHA256}, \mathrm{SHA512}\}\).
- \(\mathrm{HmacTagSize} \in \mathbb{N}\).
تستوفي المفاتيح الصالحة أيضًا السمات التالية:
- \(\mathrm{len}(\mathrm{InitialKeyMaterial}) \geq \mathrm{DerivedKeySize}\).
- إذا \(\mathrm{HmacHashType} = \mathrm{SHA1}\) ثم \(\mathrm{HmacTagSize} \in \{10, \ldots, 20\}\).
- إذا \(\mathrm{HmacHashType} = \mathrm{SHA256}\) ثم \(\mathrm{HmacTagSize} \in \{10, \ldots, 32\}\).
- إذا \(\mathrm{HmacHashType} = \mathrm{SHA512}\) ثم \(\mathrm{HmacTagSize} \in \{10, \ldots, 64\}\).
- \(\mathrm{CiphertextSegmentSize} > \mathrm{DerivedKeySize} + \mathrm{HmacTagSize} + 8\) (هذا يساوي \(\mathrm{len}(\mathrm{Header}) + \mathrm{HmacTagSize}\) كما هو موضّح لاحقًا).
ترفض 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{DerivedKeySize} + 32\) لهذه الرسالة: \(k := \mathrm{HKDF}(\mathrm{InitialKeyMaterial}, \mathrm{Salt}, \mathrm{AssociatedData})\). يتم استخدام المدخلات في المدخلات المقابلة لها في \(\mathrm{HKDF}\): \(\mathrm{InitialKeyMaterial}\) هو \(\mathrm{ikm}\)، \(\mathrm{Salt}\) هو الملح، \(\mathrm{AssociatedData}\) يُستخدَم ك \(\mathrm{info}\).
بعد ذلك، يتم تقسيم السلسلة \(k\) إلى جزأين \(k_1 \| k_2 := k\)، بحيث يكون\(\mathrm{len}(k_1) = \mathrm{DerivedKeySize}\) و \(\mathrm{len}(k_2) = 32\).
تقسيم الرسالة
بعد ذلك، يتم تقسيم الرسالة \(M\) إلى أجزاء: \(M = M_0 \| M_1 \| \cdots \| M_{n-1}\).
يتم اختيار أطوالها بحيث تستوفي ما يلي:
- \(\mathrm{len}(M_0) \in \{0,\ldots, \mathrm{CiphertextSegmentSize} - \mathrm{len}(\mathrm{Header}) - \mathrm{HmacTagSize}\}\).
- إذا \(n > 1\)، ثم \(\mathrm{len}(M_1), \ldots, \mathrm{len}(M_{n-1}) \in \{1,\ldots, \mathrm{CiphertextSegmentSize} - \mathrm{HmacTagSize}\}\).
- إذا كان \(n > 1\)، يجب أن يكون \(M_{0}, \ldots, M_{n-2}\) الحد الأقصى لطول وفقًا للقيود المذكورة أعلاه.
في عملية التقسيم هذه، يمكن أن يكون \(n\) \(2^{32}\)كحد أقصى. بخلاف ذلك، لن يتم التشفير.
تشفير الكتل
لتشفير الجزء \(M_i\)، نحسب أولاً
\(\mathrm{IV}_i := \mathrm{NoncePrefix} \| \mathrm{i} \| b \| 0x00000000\)،
حيث نُشفِّر \(\mathrm{i}\) في 4
بايت باستخدام ترميز big-endian، ونضبط البايت $b$ على 0x00
إذا كان $i < n-1$
و0x01
في الحالات الأخرى.
بعد ذلك، نشفّر \(M_i\) باستخدام مفتاح AES CTR \(k_1\)ومتّجه الإعداد \(\mathrm{IV}_i\). بعبارة أخرى، تكون مدخلات عمليات استدعاء AES هي \(\mathrm{IV}_i, \mathrm{IV}_i + 1, \mathrm{IV}_i + 2, \ldots\) حيث يتم تفسير \(\mathrm{IV}_i\) على أنّه عدد صحيح بترتيب ذي القيمة الأكبر أولاً. ينتج عن ذلك \(C'_i\).
نحسب العلامة باستخدام HMAC مع دالة التجزئة التي تحدّدها \(\mathrm{HmacHashType}\) ومع المفتاح \(k_2\) على التسلسل\(\mathrm{IV}_i \| C'_i\).
بعد ذلك، نربط النص المشفَّر متبوعًا بالعلامة للحصول على \(C_i\).
تسلسل الشرائح
أخيرًا، يتم تسلسل جميع الأجزاء على النحو التالي: \(\mathrm{Header} \| C_0 \| \cdots \| C_{n-1}\)، وهو النص المشفَّر النهائي.
دالة فك التشفير
إنّ عملية فك التشفير هي ببساطة عملية عكسية لعملية التشفير. نستخدم الرأس للحصول على المفتاح المؤقت، وفك ترميز كل جزء من النص المشفَّر بشكلٍ فردي.
قد تسمح واجهات برمجة التطبيقات (وعادةً ما تسمح) بالوصول العشوائي أو الوصول إلى بداية ملف بدون فحص نهايته. وهذا الإجراء مقصود، لأنّه من الممكن فك تشفير \(M_i\) من \(C_i\)، بدون فك تشفير جميع وحدات النص المشفَّر السابقة والباقيّة.
ومع ذلك، يجب أن تحرص واجهات برمجة التطبيقات على عدم السماح للمستخدمين بإدخال أخطاء في نهاية الملف و أخطاء في فك التشفير: في كلتا الحالتَين، من المحتمل أن تعرض واجهة برمجة التطبيقات خطأ، وقد يؤدي تجاهل الفرق إلى تمكّن المهاجم من اقتطاع الملفات بفعالية.
تسلسل المفاتيح وتحليلها
لتسلسل مفتاح بتنسيق "Tink Proto"، نربط أولاً المَعلمات
بالطريقة الواضحة في ملف proto الوارد في
aes_ctr_hmac_streaming.proto.
يجب ضبط الحقل version
على 0.
بعد ذلك، نُسلسل ذلك باستخدام تسلسل proto العادي، ونُدمج السلسلة الناتجة في قيمة حقل ملف proto لـ
KeyData. نضبط الحقل type_url
على type.googleapis.com/google.crypto.tink.AesCtrHmacStreamingKey
.
بعد ذلك، نضبط key_material_type
على SYMMETRIC
، ونضمّن ذلك في مجموعة مفاتيح. ننصح عادةً بضبط output_prefix_type
على RAW
. الاستثناء هو إذا تم تحليل المفتاح
بقيمة مختلفة تم ضبطها على output_prefix_type
،
قد يكتب Tink إما RAW
أو القيمة السابقة.
لتحليل مفتاح، نعكس العملية أعلاه (بالطريقة المعتادة عند تحليل
protos). يتم تجاهل الحقل key_material_type
. يمكن تجاهل قيمة
output_prefix_type
أو رفض المفاتيح التي
لها قيمة output_prefix_type
مختلفة عن RAW
.
يتم رفض المفاتيح التي تحتوي على version
مختلف عن 0.
المراجع
-
[HRRV15] Hoang, Reyhanitabar, Rogaway, Vizar. التشفير المعتمَد على الإنترنت ومقاومته لإعادة استخدام المفتاح المؤقت CRYPTO 2015. https://eprint.iacr.org/2015/189 ↩
-
[HS20] أمان تشفير البث في مكتبة Tink من Google Hoang, Shen, 2020. https://eprint.iacr.org/2020/1019 ↩
-
[HKDF] دالة اشتقاق المفاتيح المستندة إلى HMAC (HKDF)، RFC 5869. https://www.rfc-editor.org/rfc/rfc5869 ↩