الاتّساق

من المهم أن تعمل Tink "بالطريقة نفسها" في جميع لغات البرمجة. هذا المفهوم ليس بسيطًا، ولكن الأهم من ذلك:

للحفاظ على الاتساق، تستخدم Tink اختبارات عبر اللغات يمكن العثور عليها في مستودع GitHub عبر اللغات. تتحقّق هذه الاختبارات من اتساق اللغات المختلفة وقابلية التشغيل التفاعلي بينها.

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

السياق

على مستوى عالٍ، توفّر Tink واجهات برمجة التطبيقات التالية:

  • التلاعب بمجموعة المفاتيح: توفّر Tink واجهات برمجة تطبيقات لإضافة مفاتيح جديدة إلى مجموعة مفاتيح، وإزالة مفاتيح من مجموعة مفاتيح، وتغيير المفتاح الأساسي في مجموعة مفاتيح.

  • تسلسل مجموعة المفاتيح: توفّر Tink واجهات برمجة تطبيقات لتسلسل مجموعة مفاتيح إلى تسلسل من وحدات البايت، وتحليل مجموعة مفاتيح من تسلسل من وحدات البايت.

  • إنشاء العناصر الأساسية: توفّر Tink واجهة برمجة تطبيقات لإنشاء واجهة لعنصر أساسي من مجموعة مفاتيح. على سبيل المثال، لإنشاء عنصر Aead من مجموعة مفاتيح في Java، يستدعي المستخدم keysetHandle.getPrimitive(config, Aead.class).

  • استخدام العناصر الأساسية: توفّر الواجهة التي تم إنشاؤها في خطوة إنشاء العناصر الأساسية واجهة برمجة تطبيقات لإجراء عمليات التشفير.

هناك سؤالان مهمان يجب طرحهما حول واجهات برمجة التطبيقات هذه:

  • الإنشاء: بالنسبة إلى مجموعة مفاتيح متسلسلة ولغة ومكوّن أولي معيّن، هل من الممكن إنشاء المكوّن الأولي من مجموعة المفاتيح هذه باللغة؟

  • التقييم: إذا كان من الممكن إنشاء عنصر أساسي بلغة معيّنة من مجموعة مفاتيح معيّنة، كيف يتصرّف العنصر الأساسي؟

من المهم ملاحظة أنّ Tink لا يوفّر الاتساق عند تحليل مجموعة مفاتيح. على سبيل المثال، من الممكن أن تكون Tink C++‎

  • يحلّل بنجاح مجموعات المفاتيح التي تحتوي على مفاتيح CHACHA20-POLY1305، على الرغم من أنّ عمليات AEAD من نوع CHACHA20-POLY1305 غير مفعّلة في Tink
  • بتحليل مجموعات المفاتيح التي تحتوي على مفاتيح بطول بايت واحد بنجاح، ولكنّها ستفشل في جميع عمليات التشفير.

قد تتغيّر هذه السلوكيات في أرقام الإصدارات الثانوية.

اتّساق التقييم

يُعدّ اتساق التقييم أكثر أهمية من أي اتساق في عملية الإنشاء: إذا لم يتمكّن AEAD في Java من فك تشفير AEAD في C++‎، سيواجه المستخدمون مشكلة خطيرة.

بشكل عام، تهدف Tink إلى أن تكون متسقة بالطريقة الواضحة للأساسيات. على سبيل المثال، إذا كان ملف C++‎ الثنائي يحسب توقيعًا باستخدام public_key_sign->Sign(data)، من المتوقّع أن ينجح طلب التحقّق من Java المقابل publicKeyVerify.verify(signature, data).

ومع ذلك، هناك بعض التحذيرات هنا أيضًا. على سبيل المثال، نوع القيمة التي تم إرجاعها من aead.Encrypt في Java هو byte[]. وفقًا لمواصفات لغة Java‏ (JLS) الفقرة 10.7، يكون طول المصفوفة من النوع int والذي يمكن أن يصل إلى 2147483647 كحد أقصى وفقًا للفقرة 4.2.1 من مواصفات لغة Java. Hence, encryption of an array with a length of 2147483647 fails in Java: encryption has some overhead, meaning the output would be too long. ومع ذلك، في اللغات الأخرى، يُسمح بنجاح التشفير لمثل هذه المدخلات.

Hence, Tink provides evaluation consistency: For a given keyset, if creation of the primitive succeeds in two languages, they behave the same.

والاستثناء هو أنّ بعض العمليات قد تفشل في بعض الظروف الاستثنائية.

الاتساق في صناعة المحتوى

لا ينجح إنشاء العناصر الأساسية دائمًا لجميع مجموعات المفاتيح. على سبيل المثال، لا تسمح Tink للمستخدمين بإنشاء AesSivKey إذا كانت مادة المفتاح بطول 128 بت.

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

يُعد اتساق الإنشاء أقل أهمية من اتساق التقييم، وهناك استثناءات لهذه القاعدة أكثر من اتساق التقييم. يتم توثيق هذه القيود في قائمة أنواع المفاتيح المتوافقة. على سبيل المثال، بالنسبة إلى نوع المفتاح ECIES، تتيح Tink اختيار المنحنى الإهليلجي الذي سيتم استخدامه للاتفاق على المفتاح، ولكن Java لا تتيح استخدام X25519. وبالتالي، يتعذّر إنشاء مفتاح باستخدام X25519 في Java.


  1. في هذا المستند، نستخدم المصطلح Keyset للإشارة إلى العنصر المسمى KeysetHandle في معظم اللغات. ↩