ออบเจ็กต์คีย์และพารามิเตอร์

ในทางปฏิบัติ 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() {...}
}

ดังที่อธิบายไว้ในส่วน Keysets, Tagging Ciphertexts คีย์บางคีย์มีข้อกำหนดสำหรับรหัสของตัวเองเมื่ออยู่ในชุดคีย์ ออบเจ็กต์ Parameters ทุกรายการมีเมธอด hasIdRequirement ซึ่งระบุว่าคีย์ที่สร้างโดยออบเจ็กต์ Parameters นี้จะมีรหัสที่จำเป็นดังกล่าวไหม

ออบเจ็กต์ AesGcmParameters ถัดไปจะแสดงเมธอด getKeySizeBytes(), getIvSizeBytes() และ getTagSizeBytes() ซึ่งจะแสดงผลความยาวของคีย์ที่ใช้ ความยาวของ IV ที่ใช้ และความยาวของแท็กที่สร้างขึ้นในหน่วยไบต์ แม้ว่า Tink จะมีฟังก์ชันเหล่านี้บางรายการเพื่อความสมบูรณ์ แต่ก็ไม่ได้อนุญาตให้สร้าง Aead สำหรับทุกตัวเลือกเสมอไป ตัวอย่างเช่น ปัจจุบัน AES GCM รองรับเฉพาะ IV 12 ไบต์เท่านั้น

นอกจากนี้ ออบเจ็กต์ 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() เสมอ และผู้ติดตั้งใช้งานคลาสคีย์ใหม่ต้องตรวจสอบการดำเนินการนี้

การใช้ Key จะต้องมีเมธอด equalsKey เพื่อเปรียบเทียบคีย์ต่างๆ ด้วย วิธีการดังกล่าวมักจะมีประโยชน์ เช่น เมื่อทดสอบการระบุแหล่งที่มาคีย์ วิธีการหนึ่งต้องมั่นใจว่าการใช้การอนุมานซ้ำจะให้ผลตอบแทนออบเจ็กต์คีย์เดียวกัน นอกจากนี้ KMS อาจต้องการตรวจสอบว่าคีย์ที่มีให้แก่ผู้ใช้ต่างๆ เท่ากันหรือไม่ (ซึ่งเกิดขึ้นในบางครั้งหากผู้ใช้ใช้คีย์ร่วมกันและอัปโหลดไปยัง KMS เดียวกันหลายครั้ง) เห็นได้ชัดว่าเราจะไม่ลบล้างเมธอด equals ของ Java เพราะจะทำให้เราต้องลบล้าง hashCode และจะไม่มีวิธีนำ hashCode ไปใช้อย่างปลอดภัยกับ equals ได้โดยที่ไม่ต้องตั้งสมมติฐานขึ้นมาเอง

ถัดไป เราต้องการเมธอด getParameters() ซึ่งจะช่วยให้ผู้ใช้ได้รับข้อมูลเดิมเกี่ยวกับพารามิเตอร์ที่ใช้สร้างคีย์

สุดท้าย AesGcmKey มีเมธอด getKeyBytes ซึ่งแสดงผลเนื้อหาคีย์ดิบ วิธีการดังกล่าวเป็นเรื่องปกติสำหรับคลาสหลักๆ เพราะเป็นวิธีการเฉพาะสำหรับประเภทนั้นๆ และให้สิทธิ์เข้าถึงเนื้อหาคีย์ที่อยู่เบื้องหลัง การใช้คีย์เหล่านั้น ทำให้ผู้ใช้สามารถ ใช้งานคีย์ดั้งเดิมที่แสดงด้วยคีย์ หรือเรียงอันดับคีย์เพื่อจัดเก็บไว้ในดิสก์หรือส่งผ่าน เครือข่าย ตัวคีย์เองมีหน้าที่ในการปกป้องเนื้อหาคีย์จากการเข้าถึงที่ไม่ได้รับอนุญาต ตัวอย่างเช่น SecretBytes ต้องใช้โทเค็นเพื่อการเข้าถึงเพื่อระบุสื่อการเรียนการสอนของชั้นเรียน (ดูการควบคุมการเข้าถึง)

แป้นแบบอสมมาตร

สำหรับแบบพื้นฐานที่ไม่สมมาตร Tink จะใช้คลาสคีย์ 2 คลาส โดยรายการหนึ่งสำหรับคีย์ส่วนตัวและคลาสสำหรับคีย์สาธารณะ สำหรับพารามิเตอร์ การใช้คลาสเดียวกันจะสะดวกกว่า (เนื่องจากมีเพียงคลาสเดียวที่ใช้สร้างคีย์ได้)

นอกจากนี้ Tink ยังมีอินเทอร์เฟซ PrivateKey พร้อมฟังก์ชัน getPublicKey() เพิ่มเติมด้วย