將金鑰版本匯入 Cloud KMS

本指南說明如何將加密編譯金鑰匯入 Cloud HSM 或 Cloud Key Management Service,做為新的金鑰版本。

如要進一步瞭解匯入金鑰的詳細資料,包括限制和規定,請參閱金鑰匯入

完成本指南中的步驟只需 5 到 10 分鐘,不包括「事前準備」步驟。手動包裝金鑰會增加工作複雜度。

事前準備

建議您建立新專案來測試這項功能,方便在測試後清除資料,並確保您具備足夠的身分與存取權管理 (IAM) 權限來匯入金鑰。

匯入金鑰前,請先準備好專案、本機系統和金鑰。

準備專案

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  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. 安裝 Google Cloud CLI。

  6. 若您採用的是外部識別資訊提供者 (IdP),請先 使用聯合身分登入 gcloud CLI

  7. 執行下列指令,初始化 gcloud CLI:

    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. 安裝 Google Cloud CLI。

  12. 若您採用的是外部識別資訊提供者 (IdP),請先 使用聯合身分登入 gcloud CLI

  13. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  14. 執行匯入作業的使用者必須具備下列 IAM 權限,才能建立金鑰環、金鑰和匯入工作。如果使用者不是專案擁有者,您可以為使用者指派下列兩個預先定義的角色:

    • roles/editor
    • roles/cloudkms.importer

    如要進一步瞭解 Cloud KMS 適用的 IAM 角色和權限,請參閱「權限和角色」。

準備本機系統

請選擇下列其中一個選項,準備好本機系統。建議大多數使用者採用自動金鑰包裝。

準備金鑰

確認金鑰的演算法和長度符合支援條件。金鑰可用的演算法取決於金鑰是否用於對稱式加密、非對稱式加密或非對稱式簽署,以及金鑰是儲存在軟體還是 HSM 中。您可以在匯入要求中指定金鑰的演算法。

此外,您也必須驗證金鑰的編碼方式,並視需要進行調整。

金鑰版本建立或匯入後,就無法變更下列項目:

  • 「防護等級」會指出金鑰是保留在軟體、多租戶 HSM、單一租戶 HSM 還是外部金鑰管理系統中。金鑰材料無法從其中一個儲存環境移至另一個環境。金鑰的所有版本都具有相同的保護等級。

  • 「用途」會指出金鑰版本是否用於對稱式加密、非對稱式加密或非對稱式簽署。金鑰用途會限制可用於建立金鑰版本的演算法。金鑰的所有版本用途都相同。

如果沒有要匯入的金鑰,但想驗證金鑰匯入程序,可以使用下列指令在本機系統上建立對稱金鑰:

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

這組金鑰僅供測試,以這種方式建立的金鑰可能不適合用於正式環境。

如需手動包裝金鑰,請先完成這項作業,再繼續本指南中的程序。

建立目標金鑰和金鑰環

Cloud KMS 金鑰是容器物件,內含零或多個金鑰版本。每個金鑰版本都包含加密編譯金鑰。

將金鑰匯入 Cloud KMS 或 Cloud HSM 時,匯入的金鑰會成為現有 Cloud KMS 或 Cloud HSM 金鑰的新版本。在本指南的其餘部分,這個鍵稱為「目標鍵」。您必須先建立目標金鑰,才能將金鑰內容匯入其中。

匯入金鑰版本不會影響該金鑰的現有版本。不過,建議您在測試金鑰匯入時建立空白金鑰。空白金鑰沒有版本、處於非啟用狀態,且無法使用。

您可以選擇指定新建立的金鑰只能包含匯入的版本,避免在 Cloud KMS 中意外產生新版本。

金鑰環上已有金鑰;在本指南中,這個金鑰環稱為「目標金鑰環」。目標金鑰環的位置會決定匯入後金鑰內容的可用位置。在某些位置,您無法建立或匯入 Cloud HSM 金鑰。金鑰建立後,就無法移至其他金鑰環或位置。

請按照下列步驟,使用 Google Cloud CLI 或 Google Cloud 控制台,在新的金鑰環上建立空白金鑰。

控制台

  1. 前往 Google Cloud 控制台的「Key Management」頁面。

    前往「金鑰管理」

  2. 按一下 [Create key ring] (建立金鑰環)

  3. 在「Key ring name」(金鑰環名稱) 欄位中輸入金鑰環的名稱。

  4. 在「位置類型」下方,選取位置類型和位置。

  5. 點選「建立」。「建立金鑰」頁面隨即開啟。

  6. 在「Key name」(金鑰名稱) 欄位中,輸入金鑰的名稱。

  7. 在「防護等級」中,選取「軟體」、「HSM」或「單一租戶 HSM」

  8. 如果您選取「單一租戶 HSM」,請選取要建立金鑰的「單一租戶 HSM 執行個體」

  9. 在「金鑰內容」部分,選取「匯入的金鑰」,然後按一下「繼續」。 這樣一來,系統就不會建立初始金鑰版本。

  10. 設定金鑰的「用途」和「演算法」,然後按一下「繼續」

  11. 選用:如要讓這個金鑰只包含匯入的金鑰版本,請選取「將金鑰版本設定為僅限匯入」。這樣可避免您在 Cloud KMS 中誤建新的金鑰版本。

  12. 選用:匯入的金鑰預設會停用自動輪替功能。 如要啟用自動輪替,請從「金鑰輪替週期」欄位選取值。

    啟用自動輪替功能後,系統會在 Cloud KMS 中產生新的金鑰版本,輪替後,匯入的金鑰版本就不再是預設金鑰版本。

  13. 點選「建立」

gcloud

如要在指令列上使用 Cloud KMS,請先安裝或升級至最新版 Google Cloud CLI

  1. 建立目標金鑰環。選擇與您想使用的防護等級相容的位置。如要進一步瞭解支援的位置,請參閱「Cloud KMS 位置」。

    gcloud kms keyrings create KEY_RING \
      --location LOCATION
    

    進一步瞭解如何建立金鑰環

  2. 使用 kms keys create 指令並加上 --skip-initial-version-creation 旗標,建立目標金鑰。這樣一來,系統就會建立沒有初始金鑰版本的金鑰,因此匯入的金鑰內容會是版本 1。使用 --import-only 標記,防止 Cloud KMS 為新的金鑰版本產生金鑰內容。設定這個旗標後,您必須匯入這組金鑰的新版本。以 --import-only 建立的金鑰必須手動輪替。

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

    更改下列內容:

    • KEY_NAME:您要使用的金鑰名稱。
    • LOCATION:金鑰環的位置。
    • KEY_RING:要在其中建立金鑰的金鑰環。
    • PURPOSE:您要用於金鑰的用途
    • PROTECTION_LEVEL:您要用於金鑰的防護等級,例如 HSM

    如要建立單一租戶 Cloud HSM 金鑰,請將 --cryptoKeyBackend 旗標新增至這個指令,並新增要匯入金鑰的單一租戶 Cloud HSM 執行個體資源 ID:

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

Go

如要執行這段程式碼,請先設定 Go 開發環境,並安裝 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

如要執行這段程式碼,請先設定 Java 開發環境,然後安裝 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

如要執行這段程式碼,請先設定 Node.js 開發環境,並安裝 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: true,
    },
    // Do not allow KMS to generate an initial version of this key.
    skipInitialVersionCreation: true,
  });

  console.log(`Created key for import: ${key.name}`);
  return key;
}

return createKeyForImport();

Python

如要執行這段程式碼,請先設定 Python 開發環境,然後安裝 Cloud KMS Python SDK

from google.cloud import kms


def create_key_for_import(
    project_id: str, location_id: str, key_ring_id: str, crypto_key_id: str
) -> None:
    """

    Sets up an empty CryptoKey within a KeyRing for import.


    Args:
        project_id (string): Google Cloud project ID (e.g. 'my-project').
        location_id (string): Cloud KMS location (e.g. 'us-east1').
        key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').
        crypto_key_id (string): ID of the key to import (e.g. 'my-asymmetric-signing-key').
    """

    # Create the client.
    client = kms.KeyManagementServiceClient()

    # Build the key. For more information regarding allowed values of these fields, see:
    # https://googleapis.dev/python/cloudkms/latest/_modules/google/cloud/kms_v1/types/resources.html
    purpose = kms.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_SIGN
    algorithm = kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.EC_SIGN_P256_SHA256
    protection_level = kms.ProtectionLevel.HSM
    key = {
        "purpose": purpose,
        "version_template": {
            "algorithm": algorithm,
            "protection_level": protection_level,
        },
    }

    # Build the parent key ring name.
    key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)

    # Call the API.
    created_key = client.create_crypto_key(
        request={
            "parent": key_ring_name,
            "crypto_key_id": crypto_key_id,
            "crypto_key": key,
            # Do not allow KMS to generate an initial version of this key.
            "skip_initial_version_creation": True,
        }
    )
    print(f"Created hsm key: {created_key.name}")

API

這些範例使用 curl 做為 HTTP 用戶端,示範如何使用 API。如要進一步瞭解存取控管,請參閱「存取 Cloud KMS API」。

  1. 建立新的金鑰環:

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings?keyRingId=KEY_RING" \
        --request "POST" \
        --header "authorization: Bearer TOKEN" \
        --header "content-type: application/json" \
        --header "x-goog-user-project: PROJECT_ID" \
        --data "{}"
    

    詳情請參閱 KeyRing.create API 說明文件

  2. 建立空白的匯入專用金鑰:

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys?cryptoKeyId=KEY_NAME&skipInitialVersionCreation=true" \
        --request "POST" \
        --header "authorization: Bearer TOKEN" \
        --header "content-type: application/json" \
        --header "x-goog-user-project: PROJECT_ID" \
        --data "{"purpose":"PURPOSE", "importOnly": "true", "versionTemplate":{"protectionLevel":"PROTECTION_LEVEL","algorithm":"ALGORITHM"}}"