تستخدم مكتبة Tink مجموعات المفاتيح لتفعيل عملية تدوير المفاتيح. بشكل رسمي، مجموعة المفاتيح هي قائمة غير فارغة1 من المفاتيح يتم فيها تحديد مفتاح واحد ليكون المفتاح الأساسي (المفتاح الذي يتم استخدامه مثلاً لتوقيع وتشفير النصوص العادية الجديدة). بالإضافة إلى ذلك، تحصل المفاتيح في مجموعة المفاتيح على معرّف فريد2 وحالة مفتاح تتيح إيقاف المفاتيح بدون إزالتها من مجموعة المفاتيح.
مجموعات المفاتيح هي الطريقة الرئيسية التي يمكن للمستخدمين من خلالها الوصول إلى المفاتيح (عبر الفئة
KeysetHandle)، ما يضمن توفّر رمز لكل مستخدم للتعامل مع مفاتيح متعددة
في الوقت نفسه. بالنسبة إلى معظم مستخدمي التشفير، فإنّ التعامل مع مفاتيح متعددة هو
ضرورة، إذ يجب أن يكون من الممكن تغيير المفاتيح (قد يتم تسريب المفاتيح القديمة،
على سبيل المثال)، ولا يمكن أبدًا إجراء عملية "التبديل إلى المفتاح التالي"
التي يمكن تطبيقها على الأجهزة التي يتم تشغيل الرمز عليها وجميع النصوص المشفّرة،
على مستوى العالم، وفي لحظة واحدة. وبالتالي، يحتاج المستخدم إلى كتابة رمز يعمل عند الانتقال من مفتاح إلى آخر.
مثال: AEAD
ننصحك باستخدام مجموعة مفاتيح AEAD التي تحتوي على مفاتيح متعددة لـ AEAD الأولية. كما هو موضّح سابقًا، يحدّد كل مفتاح وظيفتَين بشكل فريد: \(\mathrm{Enc}\) و \(\mathrm{Dec}\). تحدّد مجموعة المفاتيح الآن أيضًا وظيفتَين جديدتَين: \(\mathrm{Enc}\) و \(\mathrm{Dec}\) - \(\mathrm{Enc}\) تساوي ببساطة الدالة \(\mathrm{Enc}\) للمفتاح الأساسي لمجموعة المفاتيح، بينما تحاول الدالة \(\mathrm{Dec}\) فك التشفير باستخدام جميع المفاتيح، مع المرور بها بترتيب معيّن (راجِع أدناه لمعرفة كيف يحسّن Tink أداء هذه العملية).
من الجدير بالذكر أنّ مجموعات المفاتيح هي مفاتيح كاملة:
فهي وصف كامل للوظائف \(\mathrm{Enc}\) و\(\mathrm{Dec}\) المستخدَمة. وهذا يعني أنّه يمكن للمستخدمين كتابة فئة تأخذ KeysetHandle كمدخل، مع التعبير عن فكرة أنّ الفئة تحتاج إلى وصف كامل للكائنات \(\mathrm{Enc}\) و \(\mathrm{Dec}\) لتعمل بشكل صحيح. يتيح ذلك للمستخدم كتابة واجهات برمجة تطبيقات توضّح ما يلي: لاستخدام هذه الفئة، عليك تقديم وصف لعنصر تشفير أساسي.
تدوير المفتاح
لنفترض أنّ مستخدم Tink يكتب برنامجًا يحصل أولاً على مجموعة مفاتيح من خدمة إدارة المفاتيح (KMS)، ثم ينشئ كائن AEAD من مجموعة المفاتيح هذه، وأخيرًا يستخدم هذا الكائن لتشفير نصوص مشفّرة وفك تشفيرها.
ويتم إعداد هذا المستخدم تلقائيًا لتغيير المفتاح، كما يتم تبديل الخوارزميات في حال لم يعُد الخيار الحالي يستوفي المعيار.
مع ذلك، يجب توخّي الحذر عند تنفيذ عملية تدوير المفاتيح هذه: أولاً، يجب أن تضيف خدمة إدارة المفاتيح مفتاحًا جديدًا إلى مجموعة المفاتيح (ولكن بدون ضبطه كمفتاح أساسي بعد). بعد ذلك، يجب طرح مجموعة المفاتيح الجديدة على جميع البرامج الثنائية، حتى يحتوي كل برنامج ثنائي يستخدم مجموعة المفاتيح هذه على أحدث مفتاح في مجموعة المفاتيح. عندها فقط يجب جعل المفتاح الجديد أساسيًا، ويتم توزيع مجموعة المفاتيح الناتجة مرة أخرى على جميع الملفات الثنائية التي تستخدم مجموعة المفاتيح.
المعرّفات الرئيسية في النصوص المشفرة
لنأخذ مثال مجموعة مفاتيح AEAD مرة أخرى. في حال عدم اتّخاذ الاحتياطات اللازمة، يتطلّب فك تشفير النص المشفّر أن تحاول Tink فك التشفير باستخدام جميع المفاتيح في مجموعة المفاتيح، إذ لا يمكن معرفة المفتاح المستخدَم لتشفير مجموعة المفاتيح. ويمكن أن يؤدي ذلك إلى زيادة كبيرة في تكاليف الأداء.
لهذا السبب، تسمح Tink بإضافة بادئة إلى النصوص المشفرة تتألف من سلسلة من 5 بايتات مشتقة من المعرّف. استنادًا إلى مبدأ "المفاتيح الكاملة" المذكور أعلاه، تُعدّ هذه البادئة جزءًا من المفتاح، ويجب أن تتضمّن جميع النصوص المشفرة التي تم استخلاصها باستخدام هذا المفتاح هذه البادئة. عندما ينشئ المستخدمون مفاتيح، يمكنهم اختيار ما إذا كان المفتاح سيستخدم بادئة من هذا النوع، أو ما إذا كان سيتم استخدام تنسيق نص مشفّر بدونها.
عندما يكون المفتاح في مجموعة مفاتيح، تحسب Tink هذه العلامة من رقم التعريف الذي يتضمّنه المفتاح في مجموعة المفاتيح. إنّ حقيقة أنّ المعرّفات فريدة2 ضمن مجموعة مفاتيح تعني أنّ العلامات فريدة. وبالتالي، إذا تم استخدام المفاتيح الموسومة فقط، لن يكون هناك أي انخفاض في الأداء مقارنةً بفك التشفير باستخدام مفتاح واحد، لأنّ Tink يحتاج فقط إلى تجربة أحد المفاتيح عند فك التشفير.
ومع ذلك، بما أنّ العلامة جزء من المفتاح، يعني ذلك أيضًا أنّه لا يمكن أن يكون المفتاح في مجموعة مفاتيح إلا إذا كان يتضمّن معرّفًا واحدًا محدّدًا. ويترتّب على ذلك بعض الآثار عند وصف عملية تنفيذ العناصر الأساسية بلغات مختلفة.
المفاتيح التي تتطلّب معرّفًا ولكن بدون بادئة نتائج
يجب أن تتضمّن بعض المفاتيح معرّفًا محدّدًا ولكن بدون إضافة أي بادئة إلى الناتج. على سبيل المثال، تؤدي مفاتيح التوقيع التي تتضمّن المتغير NO_PREFIX_WITH_PREHASH_ID (المخزّن مع نوع بادئة الإخراج WITH_ID_REQUIREMENT) إلى إنشاء توقيعات بدون بادئة. عند استخدام مفتاح من هذا النوع مع العنصر الأساسي Prehash، يكتب Tink معرّف المفتاح في قيمة prehash، لكي يعرف الموقّع البعيد المفتاح الذي يجب استخدامه للتوقيع.
وكما هو الحال مع المفاتيح التي تستخدم بادئة، لا يمكن أن يكون هذا المفتاح إلا في مجموعة مفاتيح ضمن معرّف واحد. معرّف المفتاح في قيمة التجزئة المسبقة هو بيانات وصفية عادية، تمامًا مثل البادئة الناتجة: لا يربط التوقيع بينهما، ولا يطّلع المدقّقون عليه أبدًا. للاطّلاع على تنسيق البايت، يُرجى الرجوع إلى تنسيق Tink السلكي.
-
لا تزال بعض أجزاء Tink تتعامل مع مجموعات المفاتيح كمجموعة. ومع ذلك، يجب تغيير هذا الإعداد. والسبب هو أنّ الترتيب مهم بشكل عام، على سبيل المثال، لنأخذ في الاعتبار دورة الحياة النموذجية لعملية تدوير المفاتيح باستخدام Aead. أولاً، تتم إضافة مفتاح جديد إلى مجموعة مفاتيح. لم يتم ضبط هذا المفتاح كمفتاح أساسي بعد، ولكنّه نشط. يتم طرح مجموعة المفاتيح الجديدة هذه على جميع الملفات الثنائية. بعد أن تتعرّف جميع الملفات الثنائية على المفتاح الجديد، يتم ضبط المفتاح كالمفتاح الأساسي (في هذه المرحلة فقط يكون استخدام هذا المفتاح آمنًا). في هذه الخطوة الثانية، يجب أن تعرف عملية تدوير المفتاح آخر مفتاح تمت إضافته. ↩
-
للتوافق مع مكتبة Google الداخلية، تتيح Tink استخدام مجموعات مفاتيح تتكرّر فيها المعرّفات. ستتم إزالة هذه الميزة في المستقبل. ↩