本指南說明如何使用抗量子匯入方法,將加密編譯金鑰匯入 Cloud Key Management Service,做為新的金鑰版本。這種做法有助於保護傳輸中的金鑰,防範未來量子電腦發動「先儲存,後解密」(SNDL) 攻擊。
抗量子金鑰匯入功能採用標準後量子密碼編譯 (PQC) 工具,包括金鑰封裝機制 (KEM) 和混合公開金鑰加密 (HPKE),可保護傳輸中的金鑰。
軟體支援的金鑰 (防護等級 SOFTWARE) 支援抗量子金鑰匯入。
事前準備
匯入金鑰前,您必須先準備好專案、本機系統和金鑰內容。
準備專案
- 登入 Google Cloud 帳戶。如果您未曾使用過 Google Cloud,歡迎 建立帳戶,親自體驗實際使用我們產品的成效。新客戶還能獲得價值 $300 美元的免費抵免額,能用於執行、測試及部署工作負載。
-
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the required API, if it is not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. 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.-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init -
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the required API, if it is not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. 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.-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
必要的角色
如要取得匯入金鑰所需的權限,請要求管理員授予您金鑰環的下列 IAM 角色:
-
如要僅匯入現有金鑰:Cloud KMS 匯入者 (
roles/cloudkms.importer) -
如要匯入至新金鑰:Cloud KMS 管理員 (
roles/cloudkms.admin)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
準備本機系統
您需要在本機系統上安裝支援後量子密碼編譯 (PQC) 工具的密碼編譯程式庫,包括金鑰封裝機制 (KEM) 和混合式公開金鑰加密 (HPKE)。您可以使用 Tink、OpenSSL 或其他支援下列項目的密碼編譯程式庫:
- 混合式公開金鑰加密 (HPKE)
- 下列其中一種 KEM 演算法:
ML-KEM-768ML-KEM-1024X-WING(ML-KEM-768和X25519的混合體)
HKDF-SHA256金鑰衍生函式 (KDF)- 使用
AES-256-GCM演算法的支援關聯資料驗證式加密 (AEAD)
準備金鑰
確認系統支援金鑰的演算法和長度。金鑰的所有版本都必須具有相同的保護層級 (SOFTWARE)。
建立指定鍵和金鑰環
匯入金鑰內容後,系統會將其做為現有金鑰的新版本。這個鍵稱為指定鍵。您必須先建立目標金鑰環和目標金鑰,才能匯入金鑰內容。
請按照下列步驟,使用 Google Cloud CLI 或 Google Cloud 控制台,在新金鑰環上建立空白的軟體支援金鑰。
控制台
前往 Google Cloud 控制台的「Key Management」(金鑰管理) 頁面。
按一下 [Create key ring] (建立金鑰環)。
在「Key ring name」(金鑰環名稱) 欄位中輸入金鑰環的名稱。
在「位置類型」下方,選取位置類型和位置。
點選「建立」。「Create key」(建立金鑰) 頁面隨即開啟。
在「Key name」(金鑰名稱) 欄位中,輸入金鑰的名稱。
在「防護等級」中,選取「軟體」。
在「金鑰內容」部分,選取「匯入的金鑰」,然後按一下「繼續」。 這樣一來,系統就不會建立初始金鑰版本。
設定金鑰的「Purpose」(用途) 和「Algorithm」(演算法),然後按一下「Continue」(繼續)。
選用:如果希望這個金鑰只包含匯入的金鑰版本,請選取「Restrict key versions to import only」(將金鑰版本設定為僅限匯入)。這樣可避免您在 Cloud KMS 中誤建新的金鑰版本。
選用:匯入的金鑰預設會停用自動輪替功能。如要啟用自動輪替功能,請在「Key rotation period」(金鑰輪替週期) 欄位中選取值。
啟用自動輪替後,Cloud KMS 會產生新的金鑰版本,輪替後,匯入的金鑰版本就不再是預設金鑰版本。
點選「建立」。
gcloud
如要在指令列使用 Cloud KMS,請先安裝或升級至最新版 Google Cloud CLI。
建立目標金鑰環。選擇與您想使用的防護等級相容的位置。如要進一步瞭解支援的位置,請參閱「Cloud KMS 位置」。
gcloud kms keyrings create KEY_RING \ --location LOCATION
如要進一步瞭解如何建立金鑰環,請參閱這篇文章。
使用
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 SOFTWARE \ --skip-initial-version-creation \ --import-only
更改下列內容:
KEY_NAME:要用於金鑰的名稱。LOCATION:金鑰環的位置。KEY_RING:要建立金鑰的金鑰環。PURPOSE:您要用於金鑰的用途。
API
這些範例使用 curl 做為 HTTP 用戶端,示範如何使用 API。如要進一步瞭解存取控管,請參閱「存取 Cloud KMS API」。
建立新的金鑰環:
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.createAPI 說明文件。建立空白的僅限匯入金鑰:
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"}}"詳情請參閱
CryptoKey.createAPI 說明文件。
金鑰環和金鑰現在已存在,但金鑰不含金鑰素材,也沒有版本,且未啟用。接著,請建立匯入工作。
建立匯入工作
匯入工作會定義匯入金鑰的特性,包括防護等級和匯入方法。
抗量子金鑰匯入僅支援 SOFTWARE 防護等級。
選擇下列其中一種抗量子匯入方法:
HPKE_KEM_XWING_HKDF_SHA256_AES_256_GCMHPKE_KEM_ML_KEM_768_HKDF_SHA256_AES_256_GCMHPKE_KEM_ML_KEM_1024_HKDF_SHA256_AES_256_GCM
gcloud
執行下列指令,建立採用抗量子匯入方法的工作:
gcloud kms import-jobs create IMPORT_JOB \
--location LOCATION \
--keyring KEY_RING \
--import-method IMPORT_METHOD \
--protection-level software
更改下列內容:
IMPORT_JOB:匯入工作的專屬名稱。LOCATION:您建立目標金鑰的金鑰環位置。KEY_RING:您建立指定鍵的金鑰環名稱。IMPORT_METHOD:要使用的抗量子匯入方法,例如hpke-kem-xwing-hkdf-sha256-aes-256-gcm。
REST
呼叫 keyRings.importJobs.create 方法:
curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/importJobs?import_job_id=IMPORT_JOB" \
--request "POST" \
--header "authorization: Bearer TOKEN" \
--header "content-type: application/json" \
--data '{"import_method": "IMPORT_METHOD", "protection_level": "SOFTWARE"}'
更改下列內容:
PROJECT_ID:Cloud KMS 專案的 ID。LOCATION:您建立目標金鑰的金鑰環位置。KEY_RING:您建立指定鍵的金鑰環名稱。IMPORT_JOB:匯入工作的專屬名稱。TOKEN:用於驗證要求的權杖。IMPORT_METHOD:要使用的抗量子匯入方法,例如HPKE_KEM_XWING_HKDF_SHA256_AES_256_GCM。
查看匯入工作的狀態
匯入工作的初始狀態為 PENDING_GENERATION。當狀態為 ACTIVE 時,您可以使用該工作匯入金鑰。
匯入工作會在三天後失效。如果匯入工作已過期,則必須建立新的工作。
您可以使用 Google Cloud CLI、Google Cloud 控制台或 Cloud Key Management Service API,檢查匯入工作的狀態。
控制台
前往 Google Cloud 控制台的「Key Management」(金鑰管理) 頁面。
按一下包含匯入工作的金鑰環名稱。
按一下頁面頂端的 [Import Jobs] (匯入工作) 分頁標籤。
狀態會顯示在該匯入作業名稱旁的 [Status] (狀態) 下方。
gcloud
如要在指令列上使用 Cloud KMS,請先安裝或升級至最新版本的 Google Cloud CLI。
匯入工作處於有效狀態時,您可以使用該工作匯入金鑰。這項作業可能需要幾分鐘才能完成。使用這個指令,確認匯入工作是否有效。請使用您建立匯入工作時的位置和金鑰環。
gcloud kms import-jobs describe IMPORT_JOB \ --location LOCATION \ --keyring KEY_RING \ --format="value(state)"
輸出結果會與下列內容相似:
state: ACTIVE
Go
如要執行這段程式碼,請先設定 Go 開發環境,並安裝 Cloud KMS Go SDK。
Java
如要執行這段程式碼,請先設定 Java 開發環境,並安裝 Cloud KMS Java SDK。
Node.js
如要執行這段程式碼,請先設定 Node.js 開發環境,並安裝 Cloud KMS Node.js SDK。
Python
如要執行這段程式碼,請先設定 Python 開發環境,並安裝 Cloud KMS Python SDK。
API
這些範例使用 curl 做為 HTTP 用戶端,示範如何使用 API。如要進一步瞭解存取控管,請參閱「存取 Cloud KMS API」。
如要檢查匯入工作的狀態,請使用 ImportJobs.get 方法:
curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/importJobs/IMPORT_JOB_ID" \
--request "GET" \
--header "authorization: Bearer TOKEN"
匯入工作啟動後,您就能匯入金鑰。
擷取公開包裝金鑰
匯入工作ACTIVE後,請擷取與其相關聯的公開金鑰。您將在本機系統上使用這個公開金鑰,包裝要匯入的金鑰內容。
gcloud
執行下列指令,下載公開金鑰:
gcloud kms import-jobs describe IMPORT_JOB \
--location LOCATION \
--keyring KEY_RING \
--format="value(publicKey.data)"
更改下列內容:
IMPORT_JOB:匯入工作的名稱。LOCATION:您建立匯入作業的金鑰環位置。KEY_RING:您建立匯入工作的金鑰環名稱。
公開金鑰採用 Base64 編碼。
REST
- 呼叫
keyRings.importJobs.get方法。 - 從回應的
publicKey.data欄位擷取公開金鑰,並在本機儲存為public_key.data。
準備及包裝金鑰內容
在本機系統上使用支援的外部加密編譯程式庫,並透過擷取的公開包裝金鑰包裝金鑰內容。
包裝程序必須執行 HPKE.Seal() (RFC 9180),才能產生包裝後的金鑰。這樣就完成了下列步驟:
- 封裝擷取的公開金鑰,產生共用密鑰和封裝金鑰。
- 使用 HKDF-SHA256,從共用密鑰衍生出臨時對稱金鑰。
- 使用 AES-256-GCM,以臨時金鑰加密金鑰內容。
- 將封裝金鑰和加密為密文的金鑰材料串連在一起。這是產生的包裝金鑰,您將使用這個金鑰匯入金鑰。將這個檔案儲存為
wrapped_key.bin。
下列 Go 程式碼範例示範如何使用 tink-go 程式庫包裝金鑰內容:
package main
import (
"bytes"
"encoding/base64"
"flag"
"fmt"
"log"
"google.golang.org/protobuf/proto"
"github.com/tink-crypto/tink-go/v2/hybrid"
"github.com/tink-crypto/tink-go/v2/keyset"
hpkepb "github.com/tink-crypto/tink-go/v2/proto/hpke_go_proto"
tinkpb "github.com/tink-crypto/tink-go/v2/proto/tink_go_proto"
)
var (
publicKeyB64Flag = flag.String("public_key", "", "Base64 encoded public key for wrapping.")
targetKeyB64Flag = flag.String("target_key", "", "Base64 encoded 32-byte target key to be wrapped.")
)
func main() {
flag.Parse()
if *publicKeyB64Flag == "" {
log.Fatal("-public_key is required")
}
if *targetKeyB64Flag == "" {
log.Fatal("-target_key is required")
}
pkBytes, err := base64.StdEncoding.DecodeString(*publicKeyB64Flag)
if err != nil {
log.Fatalf("failed to decode public key: %v", err)
}
targetKey, err := base64.StdEncoding.DecodeString(*targetKeyB64Flag)
if err != nil {
log.Fatalf("failed to decode target key: %v", err)
}
hpkePubKey := &hpkepb.HpkePublicKey{
Version: 0,
Params: &hpkepb.HpkeParams{
Kem: hpkepb.HpkeKem_ML_KEM768,
Kdf: hpkepb.HpkeKdf_HKDF_SHA256,
Aead: hpkepb.HpkeAead_AES_256_GCM,
},
PublicKey: pkBytes,
}
serializedPubKey, err := proto.Marshal(hpkePubKey)
if err != nil {
log.Fatalf("failed to marshal HPKE public key: %v", err)
}
ks := &tinkpb.Keyset{
PrimaryKeyId: 1,
Key: []*tinkpb.Keyset_Key{
{
KeyData: &tinkpb.KeyData{
TypeUrl: "type.googleapis.com/google.crypto.tink.HpkePublicKey",
Value: serializedPubKey,
KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC,
},
Status: tinkpb.KeyStatusType_ENABLED,
KeyId: 1,
OutputPrefixType: tinkpb.OutputPrefixType_RAW,
},
},
}
serializedKeyset, err := proto.Marshal(ks)
if err != nil {
log.Fatalf("failed to marshal keyset: %v", err)
}
// Create a KeysetHandle and retrieve the HybridEncrypt primitive.
reader := keyset.NewBinaryReader(bytes.NewReader(serializedKeyset))
handle, err := keyset.ReadWithNoSecrets(reader)
if err != nil {
log.Fatalf("failed to create keyset handle: %v", err)
}
enc, err := hybrid.NewHybridEncrypt(handle)
if err != nil {
log.Fatalf("failed to create hybrid encrypt primitive: %v", err)
}
// Perform the wrapping operation. Tink's HPKE implementation handles the
// 'enc || ciphertext' concatenation automatically.
wrappedKey, err := enc.Encrypt(targetKey, nil)
if err != nil {
log.Fatalf("failed to wrap key: %v", err)
}
fmt.Printf("Final wrappedKey (base64):\n%s\n", base64.StdEncoding.EncodeToString(wrappedKey))
}
儲存輸出的 Base64 字串,或將其解碼為二進位檔案:
bash
echo "BASE64_WRAPPED_KEY" | base64 --decode > wrapped_key.bin
匯入經過包裝的金鑰
將準備好的包裝金鑰匯入為目標金鑰的新金鑰版本。
gcloud
執行 kms keys versions import 指令:
gcloud kms keys versions import \
--location LOCATION \
--keyring KEY_RING \
--key KEY_NAME \
--import-job IMPORT_JOB \
--algorithm ALGORITHM \
--wrapped-key-file wrapped_key.bin
更改下列內容:
LOCATION:: 目標金鑰所在金鑰環的位置。KEY_RING:包含目標金鑰的金鑰環名稱。KEY_NAME:目標金鑰的名稱。IMPORT_JOB:匯入工作名稱。ALGORITHM:要匯入的金鑰內容演算法。
REST
呼叫 cryptoKeyVersions.import 方法:
curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions:import" \
--request "POST" \
--header "authorization: Bearer TOKEN" \
--header "content-type: application/json" \
--data '{"importJob": "IMPORT_JOB", "algorithm": "ALGORITHM", "wrappedKey": "PATH_TO_WRAPPED_KEY"}'
更改下列內容:
PROJECT_ID:Cloud KMS 專案的 ID。LOCATION:目標金鑰所在金鑰環的位置。KEY_RING:包含目標金鑰的金鑰環名稱。KEY_NAME:目標金鑰的名稱。TOKEN:用於驗證要求的權杖。IMPORT_JOB:對應匯入工作的 ID。ALGORITHM:要匯入的金鑰內容演算法。PATH_TO_WRAPPED_KEY:手動包裝金鑰的路徑,格式為 base64。
查看匯入金鑰版本的狀態
匯入金鑰版本的初始狀態為 PENDING_IMPORT。如果狀態為 ENABLED,表示金鑰版本已成功匯入。如果匯入失敗,狀態會是 IMPORT_FAILED。
您可以使用 Google Cloud CLI、Google Cloud 控制台或 Cloud Key Management Service API,檢查匯入要求的狀態。
控制台
前往 Google Cloud 控制台的「Key Management」頁面。
按一下包含匯入工作的金鑰環名稱。
按一下頁面頂端的 [Import Jobs] (匯入工作) 分頁標籤。
狀態會顯示在該匯入作業名稱旁的 [Status] (狀態) 下方。
gcloud
如要在指令列使用 Cloud KMS,請先安裝或升級至最新版 Google Cloud CLI。
請使用 versions list 指令來查看狀態。使用您在本主題稍早建立的相同位置、目標金鑰環和目標金鑰。
gcloud kms keys versions list \ --keyring KEY_RING \ --location LOCATION \ --key KEY_NAME
Go
如要執行這段程式碼,請先設定 Go 開發環境,並安裝 Cloud KMS Go SDK。
Java
如要執行這段程式碼,請先設定 Java 開發環境,並安裝 Cloud KMS Java SDK。
Node.js
如要執行這段程式碼,請先設定 Node.js 開發環境,並安裝 Cloud KMS Node.js SDK。
Python
如要執行這段程式碼,請先設定 Python 開發環境,然後安裝 Cloud KMS Python SDK。
API
這些範例使用 curl 做為 HTTP 用戶端,示範如何使用 API。如要進一步瞭解存取控管,請參閱「存取 Cloud KMS API」。
呼叫 ImportJob.get 方法,並檢查 [state][api_importjob_fields_state] 欄位。如果 state 為 PENDING_GENERATION,表示匯入工作仍在建立中。定期重新檢查狀態,直到狀態為 ACTIVE。
匯入初始金鑰版本後,金鑰狀態會變更為 ENABLED。如果是對稱金鑰,您必須將匯入的金鑰版本設為主要版本,才能使用金鑰。
重新匯入先前刪除的金鑰
如要將先前匯入、處於 DESTROYED 或 IMPORT_FAILED 狀態的金鑰版本還原為 ENABLED 狀態,可以重新匯入完全相同的金鑰內容。
重新匯入已刪除的金鑰版本時,程序與初始匯入相同,可以使用原始匯入工作或新的匯入工作 (具有相同的 SOFTWARE 保護等級)。