This document describes using key encapsulation mechanisms (KEMs) with Cloud KMS keys to establish shared secrets.
Encapsulation uses the public key of the KEM key pair, and decapsulation uses the private key of the key pair. Cloud KMS lets you retrieve the public key, which you can then use with standard libraries to encapsulate your shared secret. To decapsulate the shared secret, use Cloud KMS decapsulation methods. You can't use the private key material outside of Cloud KMS.
Before you begin
- This document provides examples that run at the command line. To simplify using the examples, use Cloud Shell. The encryption example uses OpenSSL, which is pre-installed on Cloud Shell. Otherwise, install OpenSSL on your machine.
- Create a KEM key with key purpose of
KEY_ENCAPSULATION
. To see which algorithms are supported for key purposeKEY_ENCAPSULATION
, see key encapsulation algorithms.
Grant permissions on the key
- Grant the
roles/cloudkms.publicKeyViewer
role on the key to each user or principal that must retrieve the public key to encapsulate the secret. - Grant the 'roles/cloudkms.decapsulator' role on the key to each user or principal that must decapsulate secrets with this key.
For more information about permissions and roles in Cloud KMS, see Permissions and Roles.
Encapsulation
To encapsulate using a KEM key, retrieve the public key and use the public key to encapsulate.
gcloud
This sample requires OpenSSL to be installed on your local system.
Download the public key
gcloud kms keys versions get-public-key KEY_VERSION \ --key KEY_NAME \ --keyring KEY_RING \ --location LOCATION \ --output-file PUBLIC_KEY_FILE \ --public-key-format PUBLIC_KEY_FORMAT
Replace the following:
KEY_VERSION
: The version number of the key that you want to use for encapsulation—for example,2
.KEY_NAME
: The name of the key that you want to use for encapsulation.KEY_RING
: the name of the key ring that contains the key.LOCATION
: the Cloud KMS location of the key ring.PUBLIC_KEY_FILE
: The local file path where the public key will be saved.PUBLIC_KEY_FORMAT
: The target format for the public key—for example,nist-pqc
. The default format ispem
.
Encapsulate
To create a shared secret and ciphertext, you can use the following command:
openssl pkeyutl \ -encap \ -pubin \ -inkey PEM_PUBLIC_KEY_FILE \ -out CIPHERTEXT_FILE \ -secret SHARED_SECRET_FILE
Replace the following:
PEM_PUBLIC_KEY_FILE
: The path to the downloaded public key file in PEM format.CIPHERTEXT_FILE
: The path where you want to save the resulting ciphertext.SHARED_SECRET_FILE
: The path where you want to save the resulting shared secret.
{ echo -n "MIIEsjALBglghkgBZQMEBAIDggShAA==" | base64 -d ; cat PUBLIC_KEY_FILE; } | \ openssl pkey -inform DER -pubin -pubout -out PEM_PUBLIC_KEY_FILE
Replace the following:
PUBLIC_KEY_FILE
: The path to the downloaded public key file in raw format.PEM_PUBLIC_KEY_FILE
: The path and file name to save the public key in PEM format.
Decapsulation
Use Cloud KMS to decapsulate a ciphertext.
gcloud
To use Cloud KMS on the command line, first Install or upgrade to the latest version of Google Cloud CLI.
gcloud kms decapsulate \ --version KEY_VERSION \ --key KEY_NAME \ --keyring KEY_RING \ --location LOCATION \ --ciphertext-file CIPHERTEXT_FILE \ --shared-secret-file SHARED_SECRET_FILE
Replace the following:
KEY_VERSION
: the key version to use for decapsulation—for example,3
.KEY_NAME
: the name of the key to use for decapsulation.KEY_RING
: the name of the key ring where the key is located.LOCATION
: the Cloud KMS location for the key ring.CIPHERTEXT_FILE
: the local file path for the input ciphertext.SHARED_SECRET_FILE
: the local file path for saving the output shared secret.
API
These examples use curl as an HTTP client to demonstrate using the API. For more information about access control, see Accessing the Cloud KMS API.
Use the
CryptoKeyVersions.decapsulate
method.
curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/KEY_VERSION:decapsulate" \ --request "POST" \ --header "authorization: Bearer TOKEN" \ --header "content-type: application/json" \ --data '{"ciphertext": "CIPHERTEXT"}'
Replace the following:
PROJECT_ID
: the ID of the project that contains the key ring.LOCATION
: the Cloud KMS location of the key ring.KEY_RING
: the name of the key ring that contains the key.KEY_NAME
: the name of the key to use for encryption.KEY_VERSION
: the ID of the key version to use for encryptionCIPHERTEXT
: the base64-encoded ciphertext that you want to decapsulate.