Obiekty klucza i parametrów

W praktyce Tink udostępnia obiekty Key do reprezentowania kluczy i Parameters obiekty Parameters. Na przykład w języku Java znajdują się obiekty AesGcmKey, które reprezentują klucze AES GCM.

W tej sekcji wyjaśniamy, jak te obiekty są zaprojektowane w Javie i jak współdziałają.

Parameters obiektu

Rozważmy użycie powszechnie stosowanego schematu szyfrowania AES GCM. Tink udostępnia obiekt AesGcmParameters z informacjami niezbędnymi do utworzenia AesGcmKey, co omówimy później. Hierarchia parametrów w Javie wygląda tak:

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

Jak wyjaśniliśmy w sekcji Zestawy kluczy i szyfrowane oznaczanie tagami, niektóre klucze muszą mieć określony identyfikator, jeśli znajdują się w zestawie. Każdy obiekt Parameters ma metodę hasIdRequirement, która określa, czy klucz utworzony przez ten obiekt Parameters ma wymagany identyfikator.

Następny obiekt AesGcmParameters zawiera metody getKeySizeBytes(), getIvSizeBytes() i getTagSizeBytes(). Zwracają one długość użytego klucza, długość użytego infekcji i długość utworzonego tagu w bajtach. Tink udostępnia niektóre z tych funkcji dla zapewnienia kompletności, ale nie zawsze pozwala na tworzenie elementów Aead dla każdego wyboru. Na przykład obecnie w przypadku AES GCM obsługiwane są tylko 12-bajtowe IV IV.

Obiekt AesGcmParameters udostępnia też zastąpienia wcześniej zdefiniowanych metod (oraz standardowych metod Java equals i hashCode, które są uznawane za sprawdzone metody).

Zapewnia też statyczne metody tworzenia nowych obiektów AeadParameters. Sprawdzają one dane wejściowe, tj. sprawdzają, czy rozmiar to 16, 24 lub 32.

Kluczowe obiekty

Tink ma też hierarchię kluczy. Pozostając w przykładzie AES GCM, wygląda on tak:

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

Metoda getIdRequirementOrNull zwraca identyfikator, jaki musi mieć klucz, lub null, jeśli nie ma wymogu. (Takie wymaganie dotyczące klucza wynika z faktu, że w niektórych przypadkach Tink w niektórych przypadkach dodaje tekst 0x01<id> do tekstu szyfrowania lub podpisu – zapoznaj się z sekcją poświęconą tagowaniu tekstu szyfrowania).

Będzie to zawsze zgodne z rezultatem polecenia getParameters().hasIdRequirement(), więc muszą to robić osoby implementujące nowych klas kluczy.

Implementacje funkcji Key muszą też udostępniać metodę equalsKey do porównywania różnych kluczy. Ta metoda jest często przydatna: na przykład przy testowaniu pochodnej klucza warto zadbać o to, aby wielokrotne zastosowanie pochodnej przynosiło ten sam obiekt kluczowy. Dodatkowo KMS może chcieć sprawdzić, czy którykolwiek z kluczy udostępnianych różnym użytkownikom jest jednakowy (czasem zdarza się, że użytkownicy współużytkują klucze i przesyłają je wiele razy do tego samego klucza KMS). Warto zauważyć, że nie zastępujemy metody Java equals, ponieważ wymagałoby to zastąpienia hashCode. Nie ma też sposobu na bezpieczne wdrożenie hashCode w sposób zgodny z equals bez stosowania niepotwierdzonych założeń.

Następnie wymagana jest metoda: getParameters(). Dzięki temu użytkownicy mogą uzyskać oryginalne informacje o parametrach użytych do utworzenia klucza.

AesGcmKey ma też metodę getKeyBytes, która zwraca nieprzetworzony materiał klucza. Takie metody są bardzo typowe w przypadku klas kluczy: są specyficzne dla danego typu i zapewniają dostęp do bazowego materiału klucza. Korzystając z nich, użytkownicy mogą na przykład wdrożyć element podstawowy reprezentowany w kluczu lub zserializować go, aby zapisać go na dysku lub wysłać przez sieć. Sam klucz odpowiada za ochronę materiału klucza przed nieautoryzowanym dostępem. Na przykład SecretBytes wymaga tokena dostępu, aby faktycznie dostarczyć materiał (patrz Kontrola dostępu).

Klucze asymetryczne

W przypadku asymetrycznych elementów podstawowych Tink używa 2 klas kluczy: prywatnych i publicznych. W przypadku parametrów wygodniej jest użyć tej samej klasy (ponieważ jest tylko jedna klasa, której można użyć do generowania kluczy).

Tink ma też interfejs PrivateKey z dodatkową funkcją getPublicKey().