This topic shows how to manually wrap a key before importing the key into Cloud KMS. You only need to follow the instructions in this topic if you do not want to use the Google Cloud CLI to automatically wrap the key before importing it. For an overview of the differences, refer to How key import works.
You can complete the steps in this topic in 5 to 10 minutes, not including the Before you begin steps.
Before you begin
Before you can wrap a key, you must complete the following prerequisites.
- Create a target key ring and key, and create an import job.
- Verify that your key is available locally and formatted correctly for import into Cloud KMS.
- Patch and recompile OpenSSL
Retrieve the wrapping key
This section shows how to retrieve the wrapping key from the import job you created in Before you begin. Using the Google Cloud console is recommended.
Console
Go to the Key Management page in the Google Cloud console.
Click the name of the key ring that contains your import job.
Click the Import Jobs tab at the top of the page.
Click More more_vert, then Download wrapping key in the pop-up menu.
gcloud CLI
To verify that the import job is active, run the
gcloud kms import-jobs describe
command:
gcloud kms import-jobs describe IMPORT_JOB \ --location LOCATION \ --keyring KEY_RING \ --format="value(state)"
state: ACTIVE
Run the following command to save the public key from the import job to
${HOME}/wrapping-key.pem
gcloud kms import-jobs describe \ --location=LOCATION \ --keyring=KEY_RING \ --format="value(publicKey.pem)" \ IMPORT_JOB > ${HOME}/wrapping-key.pem
API
Call the
ImportJob.get
method.Retrieve the public key via the
publicKey
field of theImportJob.get
response. This value is of typeWrappingPublicKey
. Thepem
field of theWrappingPublicKey
type is the public key encoded in Privacy Enhanced Mail (PEM) format.
For more information about the PEM-encoded format, see RFC 7468, especially the General Considerations and Textual Encoding of Subject Public Key Info sections.
Set up environment variables
The OpenSSL commands require several file paths as input values. Define environment variables for the file paths to make it easier to run the commands. Make sure you have access to write to the directories you define below.
Set the
PUB_WRAPPING_KEY
variable to the full path to the wrapping key you downloaded from the import job. The wrapping key ends in.pem
.PUB_WRAPPING_KEY="WRAPPING_KEY_PATH"
Set the
TARGET_KEY
variable to the full path to the unwrapped (target) key.TARGET_KEY=TARGET_KEY_PATH
Replace
TARGET_KEY_PATH
with the path to the.bin
file for symmetric keys or the path to the.der
file for asymmetric keys.If wrapping with RSA-AES, set the
TEMP_AES_KEY
variable to the full path to the temporary AES key.TEMP_AES_KEY=TEMP_AES_KEY_PATH
Set the
WRAPPED_KEY
variable to the full path where you want to save the wrapped target key that is ready for import.WRAPPED_KEY=WRAPPED_KEY_PATH
Verify that all the environment variables are set correctly using the following commands:
echo "PUB_WRAPPING_KEY: " ${PUB_WRAPPING_KEY}; \ echo "TARGET_KEY: " ${TARGET_KEY}; \ echo "TEMP_AES_KEY: " ${TEMP_AES_KEY}; \ echo "WRAPPED_KEY: " ${WRAPPED_KEY}
When the variables are set correctly, you are ready to wrap the key. There are two approaches as described below: with RSA only or with RSA-AES.
Wrap the key
Wrap the key with RSA
In this approach, the target key is wrapped in an RSA block. The target key size
is therefore limited. For example, you can't use this method to wrap another RSA
key. The supported import methods are rsa-oaep-3072-sha256
and
rsa-oaep-4096-sha256
.
Wrap the target key with the wrapping public key using the
CKM_RSA_PKCS_OAEP
algorithm:openssl pkeyutl \ -encrypt \ -pubin \ -inkey ${PUB_WRAPPING_KEY} \ -in ${TARGET_KEY} \ -out ${WRAPPED_KEY} \ -pkeyopt rsa_padding_mode:oaep \ -pkeyopt rsa_oaep_md:sha256 \ -pkeyopt rsa_mgf1_md:sha256
Wrap the key with RSA-AES
In this approach, the target key is wrapped with a temporary AES key. The
temporary AES key is then wrapped by the RSA key. These two wrapped keys are
concatenated and imported. Because the target key is wrapped using AES rather
than RSA, this approach can be used to wrap large keys. The supported import
methods are rsa-oaep-3072-sha1-aes-256
, rsa-oaep-4096-sha1-aes-256
,
rsa-oaep-3072-sha256-aes-256
and rsa-oaep-4096-sha256-aes-256
.
Generate a temporary random AES key that is 32 bytes long, and save it to the location identified by
${TEMP_AES_KEY}
:openssl rand -out "${TEMP_AES_KEY}" 32
Wrap the temporary AES key with the wrapping public key using the
CKM_RSA_PKCS_OAEP
algorithm. If the import method is eitherrsa-oaep-3072-sha1-aes-256
orrsa-oaep-4096-sha1-aes-256
, usesha1
forrsa_oaep_md
andrsa_mgf1_md
. Usesha256
forrsa-oaep-3072-sha256-aes-256
andrsa-oaep-4096-sha256-aes-256
.openssl pkeyutl \ -encrypt \ -pubin \ -inkey ${PUB_WRAPPING_KEY} \ -in ${TEMP_AES_KEY} \ -out ${WRAPPED_KEY} \ -pkeyopt rsa_padding_mode:oaep \ -pkeyopt rsa_oaep_md:{sha1|sha256} \ -pkeyopt rsa_mgf1_md:{sha1|sha256}
Set the
OpenSSL_V110
variable to the path of youropenssl.sh
script. If you followed the instructions for patching and recompiling OpenSSL exactly, you can use this command without modifying the value of the variable.OPENSSL_V110="${HOME}/local/bin/openssl.sh"
Wrap the target key with the temporary AES key using the
CKM_AES_KEY_WRAP_PAD
algorithm, and append it to theWRAPPED_KEY
."${OPENSSL_V110}" enc \ -id-aes256-wrap-pad \ -iv A65959A6 \ -K $( hexdump -v -e '/1 "%02x"' < "${TEMP_AES_KEY}" ) \ -in "${TARGET_KEY}" >> "${WRAPPED_KEY}"
The
-iv A65959A6
flag sets A65959A6 as the Alternate Initial Value. This is required by the RFC 5649 specification.
What's next
- The wrapped key saved at
WRAPPED_KEY
is now ready to be imported. To import the key, follow the instructions in Importing a manually-wrapped key.