Key and Parameters Objects

In practice, Tink provides Key objects to represent keys and Parameters objects to represent Parameters . For example, in Java, we have AesGcmKey objects to represent AES GCM keys.

In this section, we explain how these objects are designed in Java and how they interact.

Parameters objects

Consider AES GCM, a widely used AEAD encryption scheme. Tink provides an AesGcmParameters object with the necessary information to create a AesGcmKey , which we explain later. The parameters hierarchy in Java looks as follows:

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

As explained in the section Keysets, Tagging Ciphertexts , some keys have a requirement on their id, when they are in a keyset. Every Parameters object has a method hasIdRequirement which specifies whether the key created by this Parameters object will have such a required id, or not.

The AesGcmParameters object next provides methods getKeySizeBytes() , getIvSizeBytes() , and getTagSizeBytes() . These return the lengths of the key used, the length of the IV used, and the length of the produced tag, in bytes. While Tink provides some of these functions for completeness, it does not always allow creating Aead s for every choice. For example, currently only 12 byte IVs are supported for AES GCM.

The AesGcmParameters object also provides overrides for the previously defined methods (and the Java standard methods equals and hashCode which is considered good practice).

Finally, it provides static methods to create new AeadParameters objects. These validate the inputs, i.e., they check that the size is one of 16, 24, or 32.

Key objects

Tink also has a key hierarchy. Remaining with our example of AES GCM, it looks like this:

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

The method getIdRequirementOrNull returns the id which this key needs to have, or null if there is no requirement. (Such a requirement on the key comes from the fact that Tink in some cases prefixes ciphertexts or signatures with the string 0x01<id> , see the section on ciphertext tagging ).

This will always be consistent with the result of getParameters().hasIdRequirement() and implementers of new key classes need to ensure this.

Implementations of Key also need to provide a method equalsKey to compare different keys. Such a method is often useful: for example when testing key derivation, one is interested in ensuring that repeated application of the derivation yields the same key object. Also, a KMS might want to check if any of the keys it provides to different users are equal (which happens sometimes if users share keys and upload them to the same KMS multiple times). It is notable that we do not override the Java method equals , because this would require us to override hashCode , and there is no way to implement hashCode in a safe way compatible with equals without making unproven assumptions.

Next, we require a method getParameters() . This allows users to get the original information about the Parameters used to create the key.

Finally, AesGcmKey has a method getKeyBytes which returns the raw key material. Such methods are very typical for key classes: they are specific to the type, and provide access to the underlying key material. Using those, users can in principle e.g. implement the primitive represented by the key, or serialize the key in order to store it on disk or send it over the network. The key itself is responsible for protecting the key material against unauthorized access. For example, SecretBytes requires an access token to actually provide the material (see Access Control ).

Asymmetric Keys

For asymmetric primitives, Tink uses two Key classes, one for private and one for public keys. For the Parameters, it is more convenient to use the same class (as there is only one class which can be used to generate the keys).

Tink also has an interface PrivateKey with the additional function getPublicKey() .

Design a Mobile Site
View Site in Mobile | Classic
Share by: