ثبات

مهم است که Tink در همه زبان‌های برنامه‌نویسی «یکسان» رفتار کند. این مفهوم ساده نیست، اما مهم‌تر از همه:

برای حفظ سازگاری، Tink از آزمایش‌های چندزبانه استفاده می‌کند که می‌توانید آن‌ها را در مخزن GitHub چندزبانه پیدا کنید. این آزمایش‌ها سازگاری و قابلیت همکاری زبان‌های مختلف را تأیید می‌کنند.

بااین‌حال، تعریف سازگاری آن‌طور که انتظار می‌رود ساده نیست. بنابراین، این صفحه تعریف کاری ما را ارائه می‌دهد. اساساً Tink دو نوع سازگاری ارائه می‌دهد:

زمینه

در سطح بالا، Tink میاناهای برنامه‌سازی کاربردی زیر را ارائه می‌دهد:

  • دستکاری مجموعه کلید: Tink میاناهای برنامه‌سازی کاربردی‌ای ارائه می‌دهد که می‌توان بااستفاده از آن‌ها کلیدهای جدیدی به مجموعه کلید اضافه کرد، کلیدها را از مجموعه کلید برداشت، و کلید اصلی را در مجموعه کلید تغییر داد.

  • سریال‌سازی مجموعه کلید: Tink میاناهای برنامه‌سازی کاربردی‌ای برای سریال‌سازی مجموعه کلید به توالی بایت‌ها و برعکس، تجزیه مجموعه کلید از توالی بایت‌ها ارائه می‌دهد.

  • ایجاد اولیه: Tink یک API برای ایجاد یک رابط برای یک اولیه از یک مجموعه کلید ارائه می‌دهد. برای مثال، برای ایجاد شیء Aead از مجموعه کلید در Java، کاربر keysetHandle.getPrimitive(config, Aead.class) را فراخوانی می‌کند.

  • استفاده از اولیه: میانای تولیدشده در مرحله ایجاد اولیه میانای برنامه‌سازی کاربردی‌ای برای انجام عملیات رمزنگاری ارائه می‌دهد.

دو سؤال مهم درباره این میاناهای برنامه‌سازی کاربردی وجود دارد:

  • ایجاد: برای یک مجموعه کلید سریالی، زبان، و اولیه مشخص، آیا امکان ایجاد اولیه از این مجموعه کلید در آن زبان وجود دارد؟

  • ارزیابی: اگر بتوان یک اولیه را در زبانی از یک مجموعه کلید معین ایجاد کرد، شیء اولیه چگونه رفتار می‌کند؟

توجه به این نکته مهم است که Tink هنگام تجزیه کردن مجموعه کلید، سازگاری ارائه نمی‌دهد. برای مثال، ممکن است Tink C++‎

  • مجموعه‌کلیدهای حاوی کلیدهای CHACHA20-POLY1305 را با موفقیت تجزیه می‌کند، هرچند عملیات CHACHA20-POLY1305 AEAD در Tink پیاده‌سازی نشده است؛
  • مجموعه‌کلیدهای دارای کلیدهای ۱ بایتی را باموفقیت تجزیه می‌کند، که در همه عملیات رمزنگاری ناموفق خواهد بود.

این رفتارها ممکن است در نسخه‌های جزئی تغییر کند.

ثبات ارزیابی

ثبات ارزیابی مهم‌تر از هرگونه ثبات در فرایند ایجاد است: اگر AEAD در Java نتواند رمزگذاری AEAD در C++‎ را رمزگشایی کند، کاربران با مشکل جدی مواجه می‌شوند.

به‌طور کلی، Tink قصد دارد به روشی واضح برای اولیه‌ها سازگار باشد. برای مثال، اگر یک باینری C++‎ امضایی را با public_key_sign->Sign(data) محاسبه کند، انتظار می‌رود که فراخوانی درستی‌سنجی Java مربوطه publicKeyVerify.verify(signature, data) موفقیت‌آمیز باشد.

بااین‌حال، حتی در اینجا نیز هشدارهایی وجود دارد. برای مثال، نوع پاسخ aead.Encrypt در Java،‏ byte[] است. طبق «مشخصات زبان جاوا» (JLS) بخش ۱۰٫۷، طول آرایه از نوع int است که طبق JLS بخش ۴٫۲٫۱ می‌تواند حداکثر ۲۱۴۷۴۸۳۶۴۷ باشد. بنابراین، رمزگذاری آرایه‌ای با طول ۲۱۴۷۴۸۳۶۴۷ در Java ناموفق است: رمزگذاری سربار دارد، یعنی خروجی بیش‌ازحد طولانی خواهد بود. بااین‌حال، در زبان‌های دیگر، رمزگذاری برای چنین ورودی‌هایی مجاز است.

بنابراین، Tink سازگاری ارزیابی را ارائه می‌دهد: برای یک مجموعه کلید معین، اگر ایجاد اولیه در دو زبان موفقیت‌آمیز باشد، رفتار آن‌ها یکسان است.

استثنا این است که ممکن است برخی‌از عملیات‌ها در برخی شرایط استثنایی ناموفق باشند.

ثبات در تولید محتوا

ایجاد اولیه همیشه برای همه مجموعه‌کلیدها موفقیت‌آمیز نیست. برای مثال، Tink به کاربران اجازه نمی‌دهد AesSivKey ایجاد کنند اگر طول داده‌های کلید ۱۲۸ بیت باشد.

بااین‌حال، Tink به‌صورت زیر سازگاری ارائه می‌دهد: اگر دو زبان از یک نوع کلید پشتیبانی کنند، مجموعه کلیدهایی که می‌توان برای آن‌ها پایه ایجاد کرد باهم مطابقت دارند. البته اگر زبانی از نوع کلید پشتیبانی نکند، هیچ شیء اولیه‌ای نمی‌تواند ایجاد شود.

ثبات در ایجاد اهمیت کمتری نسبت به ثبات در ارزیابی دارد و استثناهای بیشتری برای این قانون نسبت به ثبات در ارزیابی وجود دارد. این محدودیت‌ها در فهرست انواع کلیدهای پشتیبانی‌شده ما مستند شده است. برای مثال، برای نوع کلید ECIES،‏ Tink انتخاب می‌کند که از کدام منحنی بیضوی برای توافق کلید استفاده شود، اما Java از X25519 پشتیبانی نمی‌کند. بنابراین، ایجاد کلید بااستفاده از X25519 در Java ناموفق است.


  1. در این سند، از اصطلاح Keyset برای اشاره به شیئی استفاده می‌کنیم که در اکثر زبان‌ها KeysetHandle نامیده می‌شود. ↩