Objetos de clave y parámetros

En la práctica, Tink proporciona objetos Key para representar claves y objetos Parameters para representar Parameters. Por ejemplo, en Java, tenemos objetos AesGcmKey para representar claves de GCM de AES.

En esta sección, explicamos cómo se diseñan estos objetos en Java y cómo interactúan.

Parameters objetos

Considera AES GCM, un esquema de encriptación AEAD muy utilizado. Tink proporciona un objeto AesGcmParameters con la información necesaria para crear un AesGcmKey, que explicaremos más adelante. La jerarquía de parámetros en Java se ve de la siguiente manera:

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

Como se explica en la sección Conjuntos de claves y etiquetado de textos cifrados, algunas claves tienen un requisito en su ID cuando se encuentran en un conjunto de claves. Cada objeto Parameters tiene un método hasIdRequirement que especifica si la clave creada por este objeto Parameters tendrá ese ID obligatorio o no.

A continuación, el objeto AesGcmParameters proporciona los métodos getKeySizeBytes(), getIvSizeBytes() y getTagSizeBytes(). Estas muestran la longitud de la clave usada, la longitud del IV usada y la longitud de la etiqueta generada, en bytes. Si bien Tink proporciona algunas de estas funciones para que sean completas, no siempre permite crear objetos Aead para cada opción. Por ejemplo, actualmente solo se admiten IV de 12 bytes para AES GCM.

El objeto AesGcmParameters también proporciona anulaciones para los métodos definidos con anterioridad (y los métodos estándar de Java equals y hashCode, que se considera una práctica recomendada).

Por último, proporciona métodos estáticos para crear nuevos objetos AeadParameters. Estos validan las entradas, es decir, comprueban que el tamaño sea uno de 16, 24 o 32.

Objetos de clave

Tink también tiene una jerarquía de claves. Aún con nuestro ejemplo de AES GCM, se ve de la siguiente manera:

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

El método getIdRequirementOrNull muestra el ID que necesita esta clave o null si no hay ningún requisito. (Un requisito para la clave se debe al hecho de que Tink, en algunos casos, usa la string 0x01<id> como prefijo del texto cifrado o las firmas. Consulta la sección sobre etiquetado de texto cifrado).

Esto siempre será coherente con el resultado de getParameters().hasIdRequirement(), y los implementadores de clases de clave nuevas deben garantizarlo.

Las implementaciones de Key también deben proporcionar un método equalsKey para comparar diferentes claves. Este método suele ser útil: por ejemplo, cuando se prueba la derivación de claves, nos interesa garantizar que la aplicación repetida de la derivación produzca el mismo objeto de clave. Además, es posible que un KMS quiera verificar si alguna de las claves que proporciona a diferentes usuarios es igual (lo cual sucede a veces si los usuarios comparten claves y las suben al mismo KMS varias veces). Cabe destacar que no anulamos el método equals de Java, ya que esto requeriría anular hashCode, y no hay forma de implementar hashCode de manera segura y compatible con equals sin hacer suposiciones no comprobadas.

A continuación, necesitamos un método getParameters(). Esto permite que los usuarios obtengan la información original sobre los parámetros que se usaron para crear la clave.

Por último, AesGcmKey tiene un método getKeyBytes que muestra el material de clave sin procesar. Esos métodos son muy típicos de las clases de clave: son específicos del tipo y proporcionan acceso al material de clave subyacente. Con estos, los usuarios pueden, en principio, p.ej., implementar la primitiva que representa la clave o serializar la clave para almacenarla en el disco o enviarla a través de la red. La clave en sí misma es responsable de proteger el material de la clave contra el acceso no autorizado. Por ejemplo, SecretBytes requiere un token de acceso para proporcionar el material (consulta Control de acceso).

Claves asimétricas

En el caso de las primitivas asimétricas, Tink usa dos clases de clave: una para las privadas y otra para las públicas. Para los parámetros, es más conveniente usar la misma clase (ya que solo hay una clase que se puede usar para generar las claves).

Tink también tiene una interfaz PrivateKey con la función adicional getPublicKey().