이 가이드에서는 양자 내성 가져오기 방법을 사용하여 암호화 키를 Cloud Key Management Service로 새 키 버전으로 가져오는 방법을 보여줍니다. 이 접근 방식은 전송 중인 키를 향후 양자 컴퓨터의 '지금 수집, 나중에 복호화' (HNDL) 공격으로부터 보호하는 데 도움이 됩니다.
양자 내성 키 가져오기는 전송 중에 키를 보호하기 위해 키 캡슐화 메커니즘 (KEM) 및 하이브리드 공개 키 암호화 (HPKE)를 비롯한 표준 양자 내성 암호화(PQC) 도구를 사용합니다.
소프트웨어 지원 키 (SOFTWARE 보호 수준)의 경우 양자 내성 키 가져오기가 지원됩니다.
시작하기 전에
키를 가져오기 전에 프로젝트, 로컬 시스템, 키 자료 자체를 준비해야 합니다.
프로젝트 준비
-
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.
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.-
Google Cloud CLI를 설치합니다.
-
gcloud CLI에서 제휴 ID를 사용하도록 구성합니다.
자세한 내용은 제휴 ID로 gcloud CLI에 로그인을 참고하세요.
-
gcloud CLI를 초기화하려면, 다음 명령어를 실행합니다.
gcloud init
필요한 역할
키를 가져오는 데 필요한 권한을 얻으려면 관리자에게 키링에 대한 다음 IAM 역할을 부여해 달라고 요청하세요.
-
기존 키로만 가져오려면 Cloud KMS 가져오기 작업자 (
roles/cloudkms.importer)를 사용하세요. -
새 키로 가져오기: Cloud KMS 관리자 (
roles/cloudkms.admin)
역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.
커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.
로컬 시스템 준비
키 캡슐화 메커니즘 (KEM) 및 하이브리드 공개 키 암호화 (HPKE)를 비롯한 양자 내성 암호화 (PQC) 도구를 지원하는 암호화 라이브러리가 로컬 시스템에 있어야 합니다. 다음 기능을 지원하는 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 콘솔에서 키 관리 페이지로 이동합니다.
키링 만들기를 클릭합니다.
키링 이름 필드에 키링의 이름을 입력합니다.
위치 유형에서 위치 유형과 위치를 선택합니다.
만들기를 클릭합니다. 키 만들기 페이지가 열립니다.
키 이름 필드에 키 이름을 입력합니다.
보호 수준에서 소프트웨어를 선택합니다.
키 자료에서 가져온 키를 선택한 다음 계속을 클릭합니다. 이렇게 하면 초기 키 버전이 생성되지 않습니다.
키의 용도와 알고리즘을 설정한 다음 계속을 클릭합니다.
선택사항: 이 키에 가져온 키 버전만 포함하려면 키 버전을 가져오기만 하도록 제한을 선택합니다. 이렇게 하면 Cloud KMS에서 실수로 새 키 버전을 만드는 것을 방지할 수 있습니다.
선택사항: 가져온 키의 경우 기본적으로 자동 순환이 중지됩니다. 자동 순환을 사용 설정하려면 키 순환 기간 필드에서 값을 선택합니다.
자동 순환을 사용 설정하면 Cloud KMS에 새로운 키 버전이 생성되고 순환 후 가져온 키 버전은 더 이상 기본 키 버전이 되지 않습니다.
만들기를 클릭합니다.
gcloud
명령줄에서 Cloud KMS를 사용하려면 먼저 최신 버전의 Google Cloud CLI로 설치 또는 업그레이드하세요.
대상 키링을 만듭니다. 사용하려는 보호 수준과 호환되는 위치를 선택합니다. 지원되는 위치에 대한 자세한 내용은 Cloud KMS 위치를 참고하세요.
gcloud kms keyrings create KEY_RING \ --location LOCATION
키링을 만드는 방법에 대해 자세히 알아보세요.
--skip-initial-version-creation플래그와 함께kms keys create명령어를 사용하여 타겟 키를 만듭니다. 이렇게 하면 가져온 키 자료가 버전1인 초기 키 버전이 없는 키가 생성됩니다.--import-only플래그를 사용하여 Cloud KMS가 새 키 버전의 키 자료를 생성하지 못하도록 합니다. 이 플래그가 설정되면 이 키의 새 키 버전을 가져와야 합니다.--import-only로 생성된 키는 수동으로 순환해야 합니다.gcloud kms keys create KEY_NAME \ --location LOCATION \ --keyring KEY_RING \ --purpose PURPOSE \ --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 프로젝트의 식별자입니다.LOCATION: 타겟 키를 만든 키링의 위치입니다.KEY_RING: 타겟 키를 만든 키링의 이름입니다.IMPORT_JOB: 가져오기 작업에 사용할 고유한 이름입니다.TOKEN: 요청을 인증하는 토큰입니다.IMPORT_METHOD: 사용할 양자 내성 가져오기 메서드입니다(예:HPKE_KEM_XWING_HKDF_SHA256_AES_256_GCM).
가져오기 작업 상태 확인
가져오기 작업의 초기 상태는 PENDING_GENERATION입니다. 상태가 ACTIVE이면 이를 사용하여 키를 가져올 수 있습니다.
가져오기 작업은 3일 후에 만료됩니다. 가져오기 작업이 만료된 경우 새 작업을 만들어야 합니다.
Google Cloud CLI,Google Cloud 콘솔 또는 Cloud Key Management Service API를 사용하여 가져오기 작업의 상태를 확인할 수 있습니다.
콘솔
Google Cloud 콘솔에서 키 관리 페이지로 이동합니다.
가져오기 작업이 있는 키링의 이름을 클릭합니다.
페이지 상단에 있는 가져오기 작업 탭을 클릭합니다.
상태가 가져오기 작업 이름 옆에 있는 상태 아래에 표시됩니다.
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
이 코드를 실행하려면 먼저 자바 개발 환경을 설정하고 Cloud KMS 자바 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 프로젝트의 식별자입니다.LOCATION: 타겟 키가 포함된 키링의 위치입니다.KEY_RING: 타겟 키가 포함된 키링의 이름입니다.KEY_NAME: 대상 키의 이름입니다.TOKEN: 요청을 인증하는 토큰입니다.IMPORT_JOB: 해당 가져오기 작업의 식별자입니다.ALGORITHM: 가져올 키 자료의 알고리즘입니다.PATH_TO_WRAPPED_KEY: base64 형식의 수동으로 래핑된 키의 경로입니다.
가져온 키 버전 상태 확인
가져온 키 버전의 초기 상태는 PENDING_IMPORT입니다. 상태가 ENABLED이면 키 버전을 성공적으로 가져온 것입니다. 가져오기에 실패하면 상태는 IMPORT_FAILED입니다.
Google Cloud CLI,Google Cloud 콘솔 또는 Cloud Key Management Service API를 사용하여 가져오기 요청의 상태를 확인할 수 있습니다.
콘솔
Google Cloud 콘솔에서 키 관리 페이지를 엽니다.
가져오기 작업이 있는 키링의 이름을 클릭합니다.
페이지 상단에 있는 가져오기 작업 탭을 클릭합니다.
상태가 가져오기 작업 이름 옆에 있는 상태 아래에 표시됩니다.
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
이 코드를 실행하려면 먼저 자바 개발 환경을 설정하고 Cloud KMS 자바 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 보호 수준)을 사용하여 초기 가져오기와 동일한 절차를 따릅니다.