Key Management with Tink

In addition to cryptographic operations Tink provides support for key management features like key versioning, key rotation, and storing keysets or encrypting with master keys in remote key management systems (KMS). To get a quick overview of Tink design, incl. key management features, you can also take a look at slides from a talk about Tink presented at Real World Crypto 2019.

Tinkey is a command-line tool that allows managing Tink's key material. Tink also provides a rich key management API (e.g., see KeysetManager).

Key, Keyset, and KeysetHandle

Tink performs cryptographic tasks via so-called primitives, each of which is defined via a corresponding interface that specifies the functionality of the primitive.

A particular implementation of a primitive is identified by a cryptographic key structure that contains all key material and parameters needed to provide the functionality of the primitive. The key structure is a protocol buffer, whose globally unique name (a.k.a. type url) is referred to as key type, and is used as an identifier of the corresponding implementation of a primitive. Any particular implementation comes in a form of a KeyManager which “understands” the key type: the manager can instantiate the primitive corresponding to a given key, or can generate new keys of the supported key type.

To take advantage of key rotation and other key management features, a Tink user works usually not with single keys, but with keysets, which are just sets of keys with some additional parameters and metadata. In particular, this extra information in the keyset determines which key is primary (i.e. will be used to create new cryptographic data like ciphertexts, or signatures), which keys are enabled (i.e. can be used to process existing cryptographic data, like decrypt ciphertext or verify signatures), and which keys should not be used any more. For more details about the structure of keys, keysets and related protocol buffers see tink.proto.

The keys in a keyset can belong to different implementations/key types, but must all implement the same primitive. Any given keyset (and any given key) can be used for one primitive only. Moreover, to protect from accidental leakage or corruption, an Tink user doesn’t work directly with keysets, but rather with KeysetHandle objects, which form a wrapper around the keysets. Creation of KeysetHandle objects can be restricted to specific factories (whose visibility can be governed by a white list), to enable control over actual storage of the keys and keysets, and so avoid accidental leakage of secret key material.

Key Management Systems

Tink/Tinkey can encrypt or decrypt keysets with master keys residing in remote KMSes. Currently, the following KMSes are supported:

On iOS, Tink can also directly load or store keysets in iOS KeyChain.

You can easily add support for in-house key management systems, without having to change anything in Tink/Tinkey. For example, when Tink/Tinkey is deployed at Google, it supports encrypting keysets with master keys stored in our internal key management system.

To encrypt Tink's key material with master keys in KMSes, you first create a master key in the KMS and tell Tink/Tinkey where the master key is by providing a master key URI.

KMSFormat of master key URIs
AWS KMSaws-kms://arn:aws:kms:<region>:<account-id>:key/<key-id>
GCP KMSgcp-kms://projects/*/locations/*/keyRings/*/cryptoKeys/*
Android Keystoreandroid-keystore://*

Every master key URI starts with a unique prefix that identifies its KMS. The prefix for AWS KMS is aws-kms://, Google Cloud KMS gcp-kms://, and Android Keystore android-keystore://.

To create master keys:


Tink/Tinkey needs credentials to connect to AWS KMS or Google Cloud KMS. Google Cloud credentials are service account JSON files that can be created and downloaded from Google Cloud Console. AWS credentials are properties files with the AWS access key ID is expected to be in the accessKey property and the AWS secret key is expected to be in the secretKey property.

Tink/Tinkey can also load the default credentials: