كائنات المفاتيح والمعلمات

من الناحية العملية، يوفّر Tink عناصر Key لتمثيل المفاتيح وكائنات Parameters لتمثيل Parameters. على سبيل المثال، في Java، لدينا كائنات AesGcmKey لتمثيل مفاتيح AES GCM.

في هذا القسم، نوضح كيفية تصميم هذه الكائنات في Java وكيفية تفاعلها.

كائنات Parameters

ضع في الاعتبار AES GCM، وهو نظام تشفير AEAD واسع الاستخدام. يوفّر تطبيق Tink العنصر AesGcmParameters بالمعلومات اللازمة لإنشاء AesGcmKey، وهو ما نوضّحه لاحقًا. يبدو التسلسل الهرمي للمعلمات في Java على النحو التالي:

public abstract class Parameters {
  public abstract boolean hasIdRequirement();
}

public abstract class AeadParameters extends Parameters {}

public final class AesGcmParameters extends AeadParameters {
  /**
   * The Variant specified how ciphertexts are [tagged](/tink/design/keysets#tagging_ciphertexts).
   */
  public static final class Variant {...}
  /** A helper object to create new AesGcmParameters. */
  public static final class Builder {...}

  public int getKeySizeBytes() {...}
  public int getIvSizeBytes() {...}
  public int getTagSizeBytes() {...}

  public Variant getVariant() {...}

  public OutputPrefixType getOutputPrefixType() {...}
  public boolean equals(Object object) {...}
  public int hashCode() {...}
}

كما هو موضّح في القسم مجموعات المفاتيح والنصوص المُشفَّرة لوضع العلامات، يكون لبعض المفاتيح متطلبات في معرِّفها، عندما تكون في مجموعة مفاتيح. يحتوي كل كائن Parameters على الطريقة hasIdRequirement التي تحدد ما إذا كان المفتاح الذي تم إنشاؤه من خلال كائن Parameters سيحتوي على هذا المعرّف المطلوب أم لا.

يوفّر الكائن AesGcmParameters بعد ذلك الطرق getKeySizeBytes() وgetIvSizeBytes() وgetTagSizeBytes(). تعرض هذه الدالة أطوال المفتاح المستخدَم وطول المفتاح IV المستخدَم وطول العلامة الناتجة بالبايت. مع أنّ تطبيق Tink يقدّم بعضًا من هذه الدوال للتأكد من اكتمالها، إلا أنّه لا يسمح دائمًا بإنشاء Aead لكل خيار. على سبيل المثال، في الوقت الحالي، لا يتوفر سوى 12 بايت من IV لـ AES GCM.

يوفّر الكائن AesGcmParameters أيضًا عمليات إلغاء للطرق المحددة مسبقًا (وطريقتَي Java العادية equals وhashCode والتي تُعتبر ممارسة جيدة).

وأخيرًا، توفّر طرقًا ثابتة لإنشاء كائنات AeadParameters جديدة. هذه التحقق من صحة المدخلات، أي أنها تتحقق من أن الحجم هو واحد من 16 أو 24 أو 32.

الكائنات الرئيسية

لدى Tink أيضًا تسلسل هرمي للمفتاح. مع الاحتفاظ بمثالنا عن AES GCM، يبدو على النحو التالي:

public abstract class Key {
  public abstract Parameters getParameters();
  public abstract @Nullable Integer getIdRequirementOrNull();
  public abstract boolean equalsKey(Key other);
}

public abstract class AeadKey extends Key {
  public abstract AeadParameters getParameters();
  public abstract Bytes getOutputPrefix();
}

public final class AesGcmKey implements AeadKey {
  public SecretBytes getKeyBytes();
  public abstract Bytes getOutputPrefix();
  public AesGcmParameters getParameters();
  public @Nullable Integer getIdRequirementOrNull();
  public boolean equalsKey(Key object);
}

تعرض الطريقة getIdRequirementOrNull المعرّف الذي يحتاج إليه هذا المفتاح، أو تعرض null إذا لم يكن هناك أي متطلبات. (يستند هذا الشرط على المفتاح إلى أنّ Tink في بعض الحالات يضع البادئات للنصوص المشفرة أو التوقيعات بالسلسلة 0x01<id>، راجِع القسم الذي يتناول وضع علامات على النص المشفّر).

وسيكون ذلك دائمًا متسقًا مع نتيجة getParameters().hasIdRequirement()، ويجب أن يتأكّد منفّذو الفئات الرئيسية الجديدة من ذلك.

ويجب أيضًا توفير طريقة equalsKey في عمليات تنفيذ Key للمقارنة بين المفاتيح المختلفة. هذه الطريقة مفيدة غالبًا: على سبيل المثال، عند اختبار اشتقاق المفتاح، يكون الشخص مهتمًا بضمان أن التطبيق المتكرر للاشتقاق يؤدي إلى نفس الكائن الرئيسي. أيضًا، قد يرغب KMS في التحقق مما إذا كان أي من المفاتيح التي يقدمها للمستخدمين المختلفين متساويًا (وهو ما يحدث أحيانًا إذا شارك المستخدمون المفاتيح وحمّلوها إلى نفس KMS عدة مرات). وتجدر الإشارة إلى أنّنا لا نتجاهل طريقة جافا equals، لأنّ ذلك سيتطلب منا تجاوز hashCode، ولا تتوفّر طريقة لتنفيذ hashCode بطريقة آمنة متوافقة مع equals بدون وضع افتراضات غير مُثبَتة.

بعد ذلك، نشترط الطريقة getParameters(). يتيح هذا للمستخدمين الحصول على المعلومات الأصلية حول المعلمات المستخدمة لإنشاء المفتاح.

أخيرًا، تستخدم AesGcmKey الطريقة getKeyBytes التي تعرض مادة المفتاح الأولي. هذه الطرق نموذجية جدًا للفئات الأساسية، فهي خاصة بالنوع وتوفر إمكانية الوصول إلى المادة الأساسية الأساسية. بناءً على ذلك، يمكن للمستخدمين مبدئيًا، على سبيل المثال، تنفيذ النموذج الأساسي الذي يمثله المفتاح، أو وضع المفتاح على شكل تسلسل من أجل تخزينه على القرص أو إرساله عبر الشبكة. ويكون المفتاح نفسه مسؤولاً عن حماية المواد الأساسية من الوصول غير المصرّح به. على سبيل المثال، يتطلب SecretBytes رمز دخول لتوفير المواد (يمكنك الاطّلاع على التحكم في الوصول).

المفاتيح غير المتماثلة

بالنسبة إلى الوحدات الأساسية غير المتماثلة، يستخدم Tink فئتين للمفاتيح، واحدة للمفاتيح الخاصة والأخرى للمفاتيح العامة. بالنسبة إلى المعلَمات، من الأسهل استخدام الفئة نفسها (لأنّ هناك فئة واحدة فقط يمكن استخدامها لإنشاء المفاتيح).

يحتوي Tink أيضًا على الواجهة PrivateKey مع الوظيفة الإضافية getPublicKey().