Oggetti chiave e parametri

In pratica, Tink fornisce oggetti Key per rappresentare chiavi e oggetti Parameters per rappresentare Parameters. Ad esempio, in Java, abbiamo oggetti AesGcmKey che rappresentano le chiavi GCM AES.

In questa sezione, spiegheremo come questi oggetti sono progettati in Java e come interagiscono.

Parameters oggetti

Prendiamo in considerazione AES GCM, uno schema di crittografia AEAD molto diffuso. Tink fornisce a un oggetto AesGcmParameters le informazioni necessarie per creare un AesGcmKey, di cui parleremo più avanti. La gerarchia dei parametri in Java è simile alla seguente:

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

Come spiegato nella sezione Set di chiavi, codifica di testi crittografati, per alcune chiavi l'ID di alcune chiavi è obbligatorio quando si trovano in un set di chiavi. Ogni oggetto Parameters ha un metodo hasIdRequirement che specifica se la chiave creata dall'oggetto Parameters avrà o meno questo ID richiesto.

L'oggetto AesGcmParameters fornisce successivamente i metodi getKeySizeBytes(), getIvSizeBytes() e getTagSizeBytes(). Questi restituiscono la lunghezza della chiave utilizzata, la lunghezza dell'IV utilizzato e la lunghezza del tag prodotto, in byte. Anche se Tink fornisce alcune di queste funzioni per completezza, non consente sempre di creare Aead per ogni scelta. Ad esempio, attualmente sono supportati solo IV da 12 byte per AES GCM.

L'oggetto AesGcmParameters fornisce inoltre override per i metodi definiti in precedenza (e per i metodi standard Java equals e hashCode, che è considerata buona pratica).

Infine, fornisce metodi statici per creare nuovi oggetti AeadParameters. Questi convalidano gli input, ovvero verificano che la dimensione sia una tra 16, 24 o 32.

Oggetti chiave

Tink ha anche una gerarchia delle chiavi. Rimanendo con l'esempio di AES GCM, il risultato è il seguente:

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

Il metodo getIdRequirementOrNull restituisce l'ID che questa chiave deve avere oppure null se non è richiesto alcun requisito. (Un tale requisito per la chiave deriva dal fatto che Tink in alcuni casi prefisse i testi criptati o le firme con la stringa 0x01<id>; consulta la sezione sul tagging dei testi criptati).

Questo sarà sempre coerente con il risultato di getParameters().hasIdRequirement() e gli utenti che implementano le nuove classi chiave devono garantire che ciò avvenga.

Le implementazioni di Key devono anche fornire un metodo equalsKey per confrontare diverse chiavi. Questo metodo è spesso utile: ad esempio, quando si testa la derivazione della chiave, si vuole garantire che l'applicazione ripetuta della derivazione restituisca lo stesso oggetto chiave. Inoltre, un KMS potrebbe voler verificare se una qualsiasi delle chiavi che fornisce a utenti diversi è uguale (il che accade a volte se gli utenti condividono chiavi e le caricano più volte sullo stesso KMS). È importante notare che non eseguiamo l'override del metodo Java equals perché questo richiederebbe di eseguire l'override di hashCode e non è possibile implementare hashCode in modo sicuro compatibile con equals senza fare ipotesi non dimostrate.

Il secondo è il metodo getParameters(). Ciò consente agli utenti di ottenere le informazioni originali sui parametri utilizzati per creare la chiave.

Infine, AesGcmKey ha il metodo getKeyBytes che restituisce il materiale della chiave non elaborato. Questi metodi sono molto tipici delle classi di chiavi: sono specifici per il tipo e forniscono accesso al materiale delle chiavi sottostante. Utilizzandoli, gli utenti possono, in linea di principio, implementare la primitiva rappresentata dalla chiave, oppure serializzare la chiave per archiviarla su disco o inviarla sulla rete. La chiave stessa è responsabile della protezione del materiale della chiave da accessi non autorizzati. Ad esempio, SecretBytes richiede un token di accesso per fornire effettivamente il materiale (consulta Controllo degli accessi).

Chiavi asimmetriche

Per le primitive asimmetriche, Tink utilizza due classi di chiavi, una per le chiavi private e una per le chiavi pubbliche. Per Parameters, è più pratico utilizzare la stessa classe (poiché esiste una sola classe che può essere utilizzata per generare le chiavi).

Tink ha anche un'interfaccia PrivateKey con la funzione aggiuntiva getPublicKey().