Đối tượng khoá và tham số

Trong thực tế, Tink cung cấp các đối tượng Key đại diện cho khoá và đối tượng Parameters đại diện cho Parameters. Ví dụ: trong Java, chúng tôi có các đối tượng AesGcmKey để đại diện cho khoá AES GCM.

Trong phần này, chúng tôi sẽ giải thích cách thiết kế của các đối tượng này trong Java và cách chúng tương tác.

Đối tượng Parameters

Hãy xem xét AES GCM, một lược đồ mã hoá AEAD được sử dụng rộng rãi. Tink cung cấp cho đối tượng AesGcmParameters thông tin cần thiết để tạo AesGcmKey. Chúng ta sẽ giải thích việc này sau. Hệ phân cấp tham số trong Java có dạng như sau:

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() {...}
}

Như đã giải thích trong phần Bộ khoá, Văn bản mật mã gắn thẻ, một số khoá có yêu cầu về mã nhận dạng khi nằm trong tập hợp khoá. Mỗi đối tượng Parameters có một phương thức hasIdRequirement chỉ định liệu khoá do đối tượng Parameters này tạo có có mã nhận dạng bắt buộc như vậy hay không.

Tiếp theo, đối tượng AesGcmParameters cung cấp các phương thức getKeySizeBytes(), getIvSizeBytes()getTagSizeBytes(). Các đối số này sẽ trả về độ dài của khoá đã sử dụng, độ dài của IV đã sử dụng và độ dài của thẻ đã tạo, tính bằng byte. Mặc dù Tink cung cấp một số hàm trong số này để hoàn thiện, nhưng không phải lúc nào Tink cũng cho phép tạo Aead cho mọi lựa chọn. Ví dụ: hiện chỉ hỗ trợ IV 12 byte cho AES GCM.

Đối tượng AesGcmParameters cũng cung cấp cơ chế ghi đè cho các phương thức đã xác định trước đó (cũng như các phương thức chuẩn Java equalshashCode được coi là một phương pháp hay).

Cuối cùng, cung cấp các phương thức tĩnh để tạo đối tượng AeadParameters mới. Các phương thức này xác thực dữ liệu đầu vào, tức là kiểm tra để đảm bảo rằng kích thước là 16, 24 hoặc 32.

Đối tượng chính

Tink cũng có một hệ thống phân cấp chính. Còn với ví dụ về AES GCM, mã này sẽ có dạng như sau:

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);
}

Phương thức getIdRequirementOrNull sẽ trả về mã nhận dạng mà khoá này cần có hoặc null nếu không có yêu cầu nào. (Do đó, yêu cầu về khoá xuất phát từ việc Tink trong một số trường hợp có tiền tố văn bản mật mã hoặc chữ ký với chuỗi 0x01<id>, hãy xem phần về gắn thẻ văn bản mật mã).

Điều này sẽ luôn nhất quán với kết quả của getParameters().hasIdRequirement() và những trình triển khai các lớp khoá mới cần đảm bảo điều này.

Việc triển khai Key cũng cần cung cấp một phương thức equalsKey để so sánh các khoá khác nhau. Phương thức như vậy thường hữu ích: chẳng hạn như khi kiểm thử quá trình dẫn xuất khoá, một phương thức muốn đảm bảo rằng việc áp dụng lặp lại quá trình dẫn xuất sẽ tạo ra cùng một đối tượng khoá. Ngoài ra, KMS có thể cần kiểm tra xem có bất kỳ khoá nào mà KMS cung cấp cho những người dùng khác nhau là như nhau hay không (điều này đôi khi xảy ra nếu người dùng chia sẻ các khoá và tải chúng lên cùng một KMS nhiều lần). Xin lưu ý rằng chúng tôi không ghi đè phương thức Java equals, vì phương thức này sẽ yêu cầu chúng tôi ghi đè hashCode và không có cách nào để triển khai hashCode theo cách tương thích an toàn với equals mà không đưa ra các giả định chưa được chứng minh.

Tiếp theo, chúng ta yêu cầu một phương thức getParameters(). Điều này cho phép người dùng nhận được thông tin gốc về các Tham số được dùng để tạo khoá.

Cuối cùng, AesGcmKey có phương thức getKeyBytes trả về phần tử khoá thô. Các phương thức như vậy rất điển hình đối với các lớp chính: chúng dành riêng cho từng loại và cung cấp quyền truy cập vào tài liệu khoá cơ bản. Theo nguyên tắc, người dùng có thể sử dụng các khoá đó, chẳng hạn như triển khai dữ liệu gốc do khoá biểu thị, hoặc chuyển đổi tuần tự khoá để lưu trữ khoá trên ổ đĩa hoặc gửi qua mạng. Bản thân khoá sẽ chịu trách nhiệm bảo vệ tài liệu chính khỏi hành vi truy cập trái phép. Ví dụ: SecretBytes yêu cầu mã truy cập để thực sự cung cấp tài liệu (xem bài viết Kiểm soát quyền truy cập).

Chìa khoá bất đối xứng

Đối với các dữ liệu nguyên gốc bất đối xứng, Tink sử dụng hai lớp Khoá, một cho các khoá riêng tư và một cho các khoá công khai. Đối với các Tham số, sẽ thuận tiện hơn nếu bạn sử dụng cùng một lớp (vì chỉ có một lớp có thể được dùng để tạo các khoá).

Tink cũng có giao diện PrivateKey với hàm bổ sung getPublicKey().