Import a key version into Cloud KMS

This guide shows you how to import a cryptographic key into Cloud HSM or Cloud Key Management Service as a new key version.

For more details about importing keys, including limitations and restrictions, see key import.

You can complete the steps in this guide in 5 to 10 minutes, not including the Before you begin steps. Wrapping the key manually adds complexity to the task.

Before you begin

We recommend that you create a new project to test this feature, to ease clean-up after testing and to ensure that you have adequate Identity and Access Management (IAM) permissions to import a key.

Before you can import a key, you need to prepare the project, the local system, and the key itself.

Preparing the project

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

  5. Install the Google Cloud CLI.

  6. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  7. To initialize the gcloud CLI, run the following command:

    gcloud init
  8. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  9. Verify that billing is enabled for your Google Cloud project.

  10. Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

  11. Install the Google Cloud CLI.

  12. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  13. To initialize the gcloud CLI, run the following command:

    gcloud init
  14. The user performing the import needs the following IAM permissions to create key rings, keys, and import jobs. If the user is not the project owner, you can assign both of the following two predefined roles to the user:

    • roles/editor
    • roles/cloudkms.importer

    For more information about available IAM roles and permissions for Cloud KMS, refer to Permissions and roles.

Preparing the local system

Prepare the local system by choosing one of the following options. Automatic key wrapping is recommended for most users.

  • If you want to allow the Google Cloud CLI to wrap your keys automatically before transmitting them to Google Cloud, you must install the Pyca cryptography library on your local system. The Pyca library is used by the import job that wraps and protects the key locally before sending it to Google Cloud.
  • If you want to wrap your keys manually, you must configure OpenSSL for manual key wrapping.

Preparing the key

Verify that your key's algorithm and length are supported. Allowable algorithms for a key depend upon whether the key is used for symmetric encryption, asymmetric encryption or asymmetric signing, as well as whether the key is stored in software or an HSM. You specify the key's algorithm as part of the import request.

Separately, you must also verify how the key is encoded, and make adjustments if necessary.

The following can't be changed for a key version after it is created or imported:

  • The protection level indicates whether the key persists in software, in a multi-tenant HSM, in a single-tenant HSM, or in an external key management system. Key material cannot be moved from one of these storage environments to another. All versions of a key have the same protection level.

  • The purpose indicates whether versions of the key are used for symmetric encryption, asymmetric encryption, or asymmetric signing. The purpose of the key limits the possible algorithms that can be used to create versions of that key. All versions of a key have the same purpose.

If you don't have a key to import but want to validate the procedure for importing keys, you can create a symmetric key on the local system, using the following command:

openssl rand 32 > ${HOME}/test.bin

Use this key for testing only. A key created this way might not be appropriate for production use.

If you need to wrap the key manually, do that before continuing with the procedures in this guide.

Create the target key and key ring

A Cloud KMS key is a container object that contains zero or more key versions. Each key version contains a cryptographic key.

When you import a key into Cloud KMS or Cloud HSM, the imported key becomes a new key version on an existing Cloud KMS or Cloud HSM key. In the rest of this guide, this key is called the target key. The target key must exist before you can import key material into it.

Importing a key version has no effect on that key's existing versions. However, It is recommended to create an empty key when testing key import. An empty key has no version, isn't active, and can't be used.

You may optionally specify that your newly created key may only contain imported versions, which prevents accidental generation of new versions in Cloud KMS.

A key exists on a key ring; in this guide, this key ring is called the target key ring. The location of the target key ring determines the location where the key material is available after import. Cloud HSM keys cannot be created or imported in some locations. After a key is created, it cannot be moved to a different key ring or location.

Follow these steps to create an empty key on a new key ring using the Google Cloud CLI or the Google Cloud console.

Console

  1. In the Google Cloud console, go to the Key Management page.

    Go to Key Management

  2. Click Create key ring.

  3. In the Key ring name field, enter the name for your key ring.

  4. Under Location type, select a location type and location.

  5. Click Create. The Create key page opens.

  6. In the Key name field, enter the name for your key.

  7. For Protection level, select Software, HSM, or Single-tenant HSM.

  8. If you selected Single-tenant HSM, then select the Single-tenant HSM instance where you want to create the key.

  9. For Key material, select Imported key and then click Continue. This prevents an initial key version from being created.

  10. Set the Purpose and Algorithm for the key and then click Continue.

  11. Optional: If you want this key to contain only imported key versions, select Restrict key versions to import only. This prevents you from accidentally creating new key versions in Cloud KMS.

  12. Optional: For imported keys, automatic rotation is disabled by default. To enable automatic rotation, select a value from the Key rotation period field.

    If you enable automatic rotation, new key versions will be generated in Cloud KMS, and the imported key version will no longer be the default key version after a rotation.

  13. Click Create.

gcloud

To use Cloud KMS on the command line, first Install or upgrade to the latest version of Google Cloud CLI.

  1. Create the target key ring. Choose a location that is compatible with the protection level that you want to use. For more information about supported locations, see Cloud KMS locations.

    gcloud kms keyrings create KEY_RING \
      --location LOCATION
    

    You can learn more about creating key rings.

  2. Create the target key using the kms keys create command with the --skip-initial-version-creation flag. This creates a key with no initial key version so that your imported key material is version 1. Use the --import-only flag to prevent Cloud KMS from generating key material for new key versions. With this flag set, new key versions for this key must be imported. Keys created as --import-only must be rotated manually.

    gcloud kms keys create KEY_NAME \
      --location LOCATION \
      --keyring KEY_RING \
      --purpose PURPOSE \
      --protection-level PROTECTION_LEVEL \
      --skip-initial-version-creation \
      --import-only
    

    Replace the following:

    • KEY_NAME: the name that you want to use for the key.
    • LOCATION: the location of the key ring.
    • KEY_RING: the key ring where you want to create the key.
    • PURPOSE: the purpose that you want to use for the key.
    • PROTECTION_LEVEL: the protection level that you want to use for the key—for example, HSM.

    To create a Single-tenant Cloud HSM key, add the --cryptoKeyBackend flag to this command and add the resource identifier of the Single-tenant Cloud HSM instance where you want to import the key:

    --crypto-key-backend="projects/INSTANCE_PROJECT/locations/LOCATION/singleTenantHsmInstances/INSTANCE_NAME"

Go

To run this code, first set up a Go development environment and install the Cloud KMS Go SDK.

import (
	"context"
	"fmt"
	"io"

	kms "cloud.google.com/go/kms/apiv1"
	"cloud.google.com/go/kms/apiv1/kmspb"
)

// createKeyForImport creates a new asymmetric signing key in Cloud HSM.
func createKeyForImport(w io.Writer, parent, id string) error {
	// parent := "projects/my-project/locations/us-east1/keyRings/my-key-ring"
	// id := "my-imported-key"

	// Create the client.
	ctx := context.Background()
	client, err := kms.NewKeyManagementClient(ctx)
	if err != nil {
		return fmt.Errorf("failed to create kms client: %w", err)
	}
	defer client.Close()

	// Build the request.
	req := &kmspb.CreateCryptoKeyRequest{
		Parent:      parent,
		CryptoKeyId: id,
		CryptoKey: &kmspb.CryptoKey{
			Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN,
			VersionTemplate: &kmspb.CryptoKeyVersionTemplate{
				ProtectionLevel: kmspb.ProtectionLevel_HSM,
				Algorithm:       kmspb.CryptoKeyVersion_EC_SIGN_P256_SHA256,
			},
			// Ensure that only imported versions may be added to this key.
			ImportOnly: true,
		},
		SkipInitialVersionCreation: true,
	}

	// Call the API.
	result, err := client.CreateCryptoKey(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to create key: %w", err)
	}
	fmt.Fprintf(w, "Created key: %s\n", result.Name)
	return nil
}

Java

To run this code, first set up a Java development environment and install the Cloud KMS Java SDK.

import com.google.cloud.kms.v1.CreateCryptoKeyRequest;
import com.google.cloud.kms.v1.CryptoKey;
import com.google.cloud.kms.v1.CryptoKey.CryptoKeyPurpose;
import com.google.cloud.kms.v1.CryptoKeyVersion.CryptoKeyVersionAlgorithm;
import com.google.cloud.kms.v1.CryptoKeyVersionTemplate;
import com.google.cloud.kms.v1.KeyManagementServiceClient;
import com.google.cloud.kms.v1.KeyRingName;
import com.google.cloud.kms.v1.ProtectionLevel;
import java.io.IOException;

public class CreateKeyForImport {

  public void createKeyForImport() throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String locationId = "us-east1";
    String keyRingId = "my-key-ring";
    String id = "my-import-key";
    createKeyForImport(projectId, locationId, keyRingId, id);
  }

  // Create a new crypto key to hold imported key versions.
  public void createKeyForImport(String projectId, String locationId, String keyRingId, String id)
      throws IOException {
    // Initialize client that will be used to send requests. This client only
    // needs to be created once, and can be reused for multiple requests. After
    // completing all of your requests, call the "close" method on the client to
    // safely clean up any remaining background resources.
    try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {
      // Build the parent name from the project, location, and key ring.
      KeyRingName keyRingName = KeyRingName.of(projectId, locationId, keyRingId);

      // Create the crypto key.
      CryptoKey createdKey =
          client.createCryptoKey(
              CreateCryptoKeyRequest.newBuilder()
                  .setParent(keyRingName.toString())
                  .setCryptoKeyId(id)
                  .setCryptoKey(
                      CryptoKey.newBuilder()
                          .setPurpose(CryptoKeyPurpose.ASYMMETRIC_SIGN)
                          .setVersionTemplate(
                              CryptoKeyVersionTemplate.newBuilder()
                                  .setProtectionLevel(ProtectionLevel.HSM)
                                  .setAlgorithm(CryptoKeyVersionAlgorithm.EC_SIGN_P256_SHA256))
                          // Ensure that only imported versions may be
                          // added to this key.
                          .setImportOnly(true))
                  .setSkipInitialVersionCreation(true)
                  .build());

      System.out.printf("Created crypto key %s%n", createdKey.getName());
    }
  }
}

Node.js

To run this code, first set up a Node.js development environment and install the Cloud KMS Node.js SDK.

//
// TODO(developer): Uncomment these variables before running the sample.
//
// const projectId = 'my-project';
// const locationId = 'us-east1';
// const keyRingId = 'my-key-ring';
// const id = 'my-imported-key';

// Imports the Cloud KMS library
const {KeyManagementServiceClient} = require('@google-cloud/kms');

// Instantiates a client
const client = new KeyManagementServiceClient();

// Build the parent key ring name
const keyRingName = client.keyRingPath(projectId, locationId, keyRingId);

async function createKeyForImport() {
  const [key] = await client.createCryptoKey({
    parent: keyRingName,
    cryptoKeyId: id,
    cryptoKey: {
      purpose: 'ENCRYPT_DECRYPT',
      versionTemplate: {
        algorithm: 'GOOGLE_SYMMETRIC_ENCRYPTION',
        protectionLevel: 'HSM',
      },
      // Optional: ensure that only imported versions may be added to this
      // key.
      importOnly: