ํ‚ค ๋งŒ๋“ค๊ธฐ

์ด ํŽ˜์ด์ง€์—์„œ๋Š” Cloud KMS์—์„œ ํ‚ค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํ‚ค๋Š” ๋Œ€์นญ ๋˜๋Š” ๋น„๋Œ€์นญ ์•”ํ˜ธํ™” ํ‚ค, ๋น„๋Œ€์นญ ์„œ๋ช… ํ‚ค์ด๊ฑฐ๋‚˜ MAC ์„œ๋ช… ํ‚ค์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ‚ค๋ฅผ ๋งŒ๋“ค ๋•Œ ํŠน์ • Cloud KMS ์œ„์น˜์˜ ํ‚ค๋ง์— ํ‚ค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ ํ‚ค๋ง์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๊ธฐ์กด ํ‚ค๋ง์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŽ˜์ด์ง€์—์„œ๋Š” ์ƒˆ Cloud KMS ๋˜๋Š” Cloud HSM ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๊ธฐ์กด ํ‚ค๋ง์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. Cloud EKM ํ‚ค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ์™ธ๋ถ€ ํ‚ค ๋งŒ๋“ค๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. Cloud KMS ๋˜๋Š” Cloud HSM ํ‚ค๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด ํ‚ค ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์‹œ์ž‘ํ•˜๊ธฐ ์ „์—

์ด ํŽ˜์ด์ง€์˜ ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋ ค๋ฉด ๋จผ์ € ๋‹ค์Œ ํ•ญ๋ชฉ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. Cloud KMS ๋ฆฌ์†Œ์Šค๋ฅผ ํฌํ•จํ•  Google Cloud ํ”„๋กœ์ ํŠธ ๋ฆฌ์†Œ์Šค. ๋‹ค๋ฅธ Google Cloud ๋ฆฌ์†Œ์Šค๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์€ Cloud KMS ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด ๊ฐœ๋ณ„ ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
  2. ํ‚ค๋ฅผ ๋งŒ๋“ค ํ‚ค๋ง์˜ ์ด๋ฆ„๊ณผ ์œ„์น˜. ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค ๊ฐ€๊นŒ์ด์— ์žˆ๊ณ  ์›ํ•˜๋Š” ๋ณดํ˜ธ ์ˆ˜์ค€์„ ์ง€์›ํ•˜๋Š” ์œ„์น˜์—์„œ ํ‚ค๋ง์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์œ„์น˜ ๋ฐ ์ง€์›๋˜๋Š” ๋ณดํ˜ธ ์ˆ˜์ค€์„ ๋ณด๋ ค๋ฉด Cloud KMS ์œ„์น˜๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. ํ‚ค๋ง์„ ๋งŒ๋“ค๋ ค๋ฉด ํ‚ค๋ง ๋งŒ๋“ค๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
  3. ์„ ํƒ์‚ฌํ•ญ: gcloud CLI๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ™˜๊ฒฝ์„ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค.

    In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    ํ•„์š”ํ•œ ์—ญํ• 

    ํ‚ค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ถŒํ•œ์„ ์–ป์œผ๋ ค๋ฉด ๊ด€๋ฆฌ์ž์—๊ฒŒ ํ”„๋กœ์ ํŠธ ๋˜๋Š” ์ƒ์œ„ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ Cloud KMS ๊ด€๋ฆฌ์ž (roles/cloudkms.admin) IAM ์—ญํ• ์„ ๋ถ€์—ฌํ•ด ๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•˜์„ธ์š”. ์—ญํ•  ๋ถ€์—ฌ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ”„๋กœ์ ํŠธ, ํด๋”, ์กฐ์ง์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ๊ด€๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    ์ด ์‚ฌ์ „ ์ •์˜๋œ ์—ญํ• ์—๋Š” ํ‚ค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ถŒํ•œ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ์ •ํ™•ํ•œ ๊ถŒํ•œ์„ ๋ณด๋ ค๋ฉด ํ•„์ˆ˜ ๊ถŒํ•œ ์„น์…˜์„ ํŽผ์น˜์„ธ์š”.

    ํ•„์ˆ˜ ๊ถŒํ•œ

    ํ‚ค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๊ถŒํ•œ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

    • cloudkms.cryptoKeys.create
    • cloudkms.cryptoKeys.get
    • cloudkms.cryptoKeys.list
    • cloudkms.cryptoKeyVersions.create
    • cloudkms.cryptoKeyVersions.get
    • cloudkms.cryptoKeyVersions.list
    • cloudkms.keyRings.get
    • cloudkms.keyRings.list
    • cloudkms.locations.get
    • cloudkms.locations.list
    • resourcemanager.projects.get
    • ๊ณต๊ฐœ ํ‚ค๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด ๋‹ค์Œ ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. cloudkms.cryptoKeyVersions.viewPublicKey

    ์ปค์Šคํ…€ ์—ญํ• ์ด๋‚˜ ๋‹ค๋ฅธ ์‚ฌ์ „ ์ •์˜๋œ ์—ญํ• ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ถŒํ•œ์„ ๋ถ€์—ฌ๋ฐ›์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋Œ€์นญ ์•”ํ˜ธํ™” ํ‚ค ๋งŒ๋“ค๊ธฐ

    ์ฝ˜์†”

    1. Google Cloud ์ฝ˜์†”์—์„œ ํ‚ค ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

      Key Management Service๋กœ ์ด๋™

    2. ํ‚ค๋ฅผ ๋งŒ๋“ค ํ‚ค๋ง์˜ ์ด๋ฆ„์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    3. ํ‚ค ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    4. ํ‚ค ์ด๋ฆ„์— ํ‚ค์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    5. ๋ณดํ˜ธ ์ˆ˜์ค€์—์„œ ์†Œํ”„ํŠธ์›จ์–ด ๋˜๋Š” HSM์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    6. ํ‚ค ์ž๋ฃŒ์—์„œ ์ƒ์„ฑ๋œ ํ‚ค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    7. ์šฉ๋„์—์„œ Symmetric encrypt/decrypt๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    8. ์ˆœํ™˜ ์ฃผ๊ธฐ ๋ฐ ์‹œ์ž‘์ผ์˜ ๊ธฐ๋ณธ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    9. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    gcloud

    ๋ช…๋ น์ค„์—์„œ Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์ตœ์‹  ๋ฒ„์ „์˜ Google Cloud CLI๋กœ ์„ค์น˜ ๋˜๋Š” ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”.

    gcloud kms keys create KEY_NAME \
        --keyring KEY_RING \
        --location LOCATION \
        --purpose "encryption" \
        --protection-level "PROTECTION_LEVEL"
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • PROTECTION_LEVEL: ํ‚ค์— ์‚ฌ์šฉํ•  ๋ณดํ˜ธ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค(์˜ˆ: software ๋˜๋Š” hsm). software ํ‚ค์˜ --protection-level ํ”Œ๋ž˜๊ทธ๋Š” ์ƒ๋žตํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

    ๋ชจ๋“  ํ”Œ๋ž˜๊ทธ ๋ฐ ๊ฐ€๋Šฅํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด --help ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

    C#

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € C# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS C# SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    
    using Google.Cloud.Kms.V1;
    
    public class CreateKeySymmetricEncryptDecryptSample
    {
        public CryptoKey CreateKeySymmetricEncryptDecrypt(
          string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring",
          string id = "my-symmetric-encryption-key")
        {
            // Create the client.
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
    
            // Build the parent key ring name.
            KeyRingName keyRingName = new KeyRingName(projectId, locationId, keyRingId);
    
            // Build the key.
            CryptoKey key = new CryptoKey
            {
                Purpose = CryptoKey.Types.CryptoKeyPurpose.EncryptDecrypt,
                VersionTemplate = new CryptoKeyVersionTemplate
                {
                    Algorithm = CryptoKeyVersion.Types.CryptoKeyVersionAlgorithm.GoogleSymmetricEncryption,
                }
            };
    
            // Call the API.
            CryptoKey result = client.CreateCryptoKey(keyRingName, id, key);
    
            // Return the result.
            return result;
        }
    }

    Go

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Go ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Go SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	kms "cloud.google.com/go/kms/apiv1"
    	"cloud.google.com/go/kms/apiv1/kmspb"
    )
    
    // createKeySymmetricEncryptDecrypt creates a new symmetric encrypt/decrypt key
    // on Cloud KMS.
    func createKeySymmetricEncryptDecrypt(w io.Writer, parent, id string) error {
    	// parent := "projects/my-project/locations/us-east1/keyRings/my-key-ring"
    	// id := "my-symmetric-encryption-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_ENCRYPT_DECRYPT,
    			VersionTemplate: &kmspb.CryptoKeyVersionTemplate{
    				Algorithm: kmspb.CryptoKeyVersion_GOOGLE_SYMMETRIC_ENCRYPTION,
    			},
    		},
    	}
    
    	// 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

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € ์ž๋ฐ” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS ์ž๋ฐ” SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    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 java.io.IOException;
    
    public class CreateKeySymmetricEncryptDecrypt {
    
      public void createKeySymmetricEncryptDecrypt() 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-key";
        createKeySymmetricEncryptDecrypt(projectId, locationId, keyRingId, id);
      }
    
      // Create a new key that is used for symmetric encryption and decryption.
      public void createKeySymmetricEncryptDecrypt(
          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);
    
          // Build the symmetric key to create.
          CryptoKey key =
              CryptoKey.newBuilder()
                  .setPurpose(CryptoKeyPurpose.ENCRYPT_DECRYPT)
                  .setVersionTemplate(
                      CryptoKeyVersionTemplate.newBuilder()
                          .setAlgorithm(CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION))
                  .build();
    
          // Create the key.
          CryptoKey createdKey = client.createCryptoKey(keyRingName, id, key);
          System.out.printf("Created symmetric 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-symmetric-encryption-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 createKeySymmetricEncryptDecrypt() {
      const [key] = await client.createCryptoKey({
        parent: keyRingName,
        cryptoKeyId: id,
        cryptoKey: {
          purpose: 'ENCRYPT_DECRYPT',
          versionTemplate: {
            algorithm: 'GOOGLE_SYMMETRIC_ENCRYPTION',
          },
        },
      });
    
      console.log(`Created symmetric key: ${key.name}`);
      return key;
    }
    
    return createKeySymmetricEncryptDecrypt();

    PHP

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Google Cloud์—์„œ PHP ์‚ฌ์šฉ์— ๊ด€ํ•ด ์•Œ์•„๋ณด๊ณ  Cloud KMS PHP SDK๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”.

    use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
    use Google\Cloud\Kms\V1\CreateCryptoKeyRequest;
    use Google\Cloud\Kms\V1\CryptoKey;
    use Google\Cloud\Kms\V1\CryptoKey\CryptoKeyPurpose;
    use Google\Cloud\Kms\V1\CryptoKeyVersion\CryptoKeyVersionAlgorithm;
    use Google\Cloud\Kms\V1\CryptoKeyVersionTemplate;
    
    function create_key_symmetric_encrypt_decrypt(
        string $projectId = 'my-project',
        string $locationId = 'us-east1',
        string $keyRingId = 'my-key-ring',
        string $id = 'my-symmetric-key'
    ): CryptoKey {
        // Create the Cloud KMS client.
        $client = new KeyManagementServiceClient();
    
        // Build the parent key ring name.
        $keyRingName = $client->keyRingName($projectId, $locationId, $keyRingId);
    
        // Build the key.
        $key = (new CryptoKey())
            ->setPurpose(CryptoKeyPurpose::ENCRYPT_DECRYPT)
            ->setVersionTemplate((new CryptoKeyVersionTemplate())
                ->setAlgorithm(CryptoKeyVersionAlgorithm::GOOGLE_SYMMETRIC_ENCRYPTION)
            );
    
        // Call the API.
        $createCryptoKeyRequest = (new CreateCryptoKeyRequest())
            ->setParent($keyRingName)
            ->setCryptoKeyId($id)
            ->setCryptoKey($key);
        $createdKey = $client->createCryptoKey($createCryptoKeyRequest);
        printf('Created symmetric key: %s' . PHP_EOL, $createdKey->getName());
    
        return $createdKey;
    }

    Python

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Python SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    from google.cloud import kms
    
    
    def create_key_symmetric_encrypt_decrypt(
        project_id: str, location_id: str, key_ring_id: str, key_id: str
    ) -> kms.CryptoKey:
        """
        Creates a new symmetric encryption/decryption key in Cloud KMS.
    
        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').
            key_id (string): ID of the key to create (e.g. 'my-symmetric-key').
    
        Returns:
            CryptoKey: Cloud KMS key.
    
        """
    
        # Create the client.
        client = kms.KeyManagementServiceClient()
    
        # Build the parent key ring name.
        key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)
    
        # Build the key.
        purpose = kms.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT
        algorithm = (
            kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION
        )
        key = {
            "purpose": purpose,
            "version_template": {
                "algorithm": algorithm,
            },
        }
    
        # Call the API.
        created_key = client.create_crypto_key(
            request={"parent": key_ring_name, "crypto_key_id": key_id, "crypto_key": key}
        )
        print(f"Created symmetric key: {created_key.name}")
        return created_key
    
    

    Ruby

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Ruby ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Ruby SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    # TODO(developer): uncomment these values before running the sample.
    # project_id  = "my-project"
    # location_id = "us-east1"
    # key_ring_id = "my-key-ring"
    # id          = "my-symmetric-key"
    
    # Require the library.
    require "google/cloud/kms"
    
    # Create the client.
    client = Google::Cloud::Kms.key_management_service
    
    # Build the parent key ring name.
    key_ring_name = client.key_ring_path project: project_id, location: location_id, key_ring: key_ring_id
    
    # Build the key.
    key = {
      purpose:          :ENCRYPT_DECRYPT,
      version_template: {
        algorithm: :GOOGLE_SYMMETRIC_ENCRYPTION
      }
    }
    
    # Call the API.
    created_key = client.create_crypto_key parent: key_ring_name, crypto_key_id: id, crypto_key: key
    puts "Created symmetric key: #{created_key.name}"

    API

    ์ด ์˜ˆ์‹œ์—์„œ๋Š” curl์„ HTTP ํด๋ผ์ด์–ธํŠธ๋กœ ์‚ฌ์šฉํ•˜์—ฌ API ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ์ œ์–ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud KMS API ์•ก์„ธ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    ํ‚ค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด CryptoKey.create ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys?crypto_key_id=KEY_NAME" \
        --request "POST" \
        --header "authorization: Bearer TOKEN" \
        --header "content-type: application/json" \
        --data '{"purpose": "ENCRYPT_DECRYPT", "versionTemplate": { "protectionLevel": "PROTECTION_LEVEL", "algorithm": "ALGORITHM" }}'
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: ํ‚ค๋ง์ด ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ID์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • PROTECTION_LEVEL: ํ‚ค์˜ ๋ณดํ˜ธ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค(์˜ˆ: SOFTWARE ๋˜๋Š” HSM).
    • ALGORITHM: HMAC ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค(์˜ˆ: HMAC_SHA256). ์ง€์›๋˜๋Š” ๋ชจ๋“  HMAC ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ณด๋ ค๋ฉด HMAC ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ์ปค์Šคํ…€ ์ž๋™ ์ˆœํ™˜์œผ๋กœ ๋Œ€์นญ ์•”ํ˜ธํ™” ํ‚ค ๋งŒ๋“ค๊ธฐ

    ํ‚ค๋ฅผ ๋งŒ๋“ค ๋•Œ ์ƒˆ๋กœ์šด ํ‚ค ๋ฒ„์ „์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ„๊ฒฉ์ธ ์ˆœํ™˜ ๊ธฐ๊ฐ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ง€๊ธˆ์œผ๋กœ๋ถ€ํ„ฐ ํ•˜๋‚˜์˜ ์ˆœํ™˜ ๊ธฐ๊ฐ„ ์ด์ „ ๋˜๋Š” ์ดํ›„์— ๋‹ค์Œ ์ˆœํ™˜์ด ๋ฐœ์ƒํ•˜๋„๋ก ๋‹ค์Œ ์ˆœํ™˜ ์‹œ๊ฐ„์„ ๋…๋ฆฝ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ฝ˜์†”

    Google Cloud ์ฝ˜์†”์„ ์‚ฌ์šฉํ•˜์—ฌ ํ‚ค๋ฅผ ๋งŒ๋“ค๋ฉด Cloud KMS๊ฐ€ ์ˆœํ™˜ ๊ธฐ๊ฐ„๊ณผ ๋‹ค์Œ ์ˆœํ™˜ ์‹œ๊ฐ„์„ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋„๋ก ์„ ํƒํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๋‹ค๋ฅธ ์ˆœํ™˜ ์ฃผ๊ธฐ์™€ ์‹œ์ž‘ ์‹œ๊ฐ„์„ ์ง€์ •ํ•˜๋ ค๋ฉด, ํ‚ค๋ฅผ ๋งŒ๋“ค ๋•Œ ๋งŒ๋“ค๊ธฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๊ธฐ ์ „์— ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    1. ํ‚ค ์ˆœํ™˜ ๊ธฐ๊ฐ„์—์„œ ์˜ต์…˜์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    2. ์‹œ์ž‘์ผ์—์„œ ์ฒซ ๋ฒˆ์งธ ์ž๋™ ์ˆœํ™˜์„ ์‹คํ–‰ํ•  ๋‚ ์งœ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์‹œ์ž‘์ผ์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ํ‚ค๋ฅผ ์ƒ์„ฑํ•œ ์‹œ์ ๋ถ€ํ„ฐ ์ฒซ ๋ฒˆ์งธ ์ž๋™ ์ˆœํ™˜ ๋‹จ์ผ ํ‚ค ์ˆœํ™˜ ๊ธฐ๊ฐ„์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    gcloud

    ๋ช…๋ น์ค„์—์„œ Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์ตœ์‹  ๋ฒ„์ „์˜ Google Cloud CLI๋กœ ์„ค์น˜ ๋˜๋Š” ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”.

    gcloud kms keys create KEY_NAME \
        --keyring KEY_RING \
        --location LOCATION \
        --purpose "encryption" \
        --rotation-period ROTATION_PERIOD \
        --next-rotation-time NEXT_ROTATION_TIME
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • ROTATION_PERIOD: ํ‚ค๋ฅผ ์ˆœํ™˜ํ•˜๋Š” ๊ฐ„๊ฒฉ์ž…๋‹ˆ๋‹ค(์˜ˆ: 30d๋Š” ํ‚ค๋ฅผ 30์ผ๋งˆ๋‹ค ์ˆœํ™˜). ์ˆœํ™˜ ๊ธฐ๊ฐ„์€ ์ตœ์†Œ 1์ผ์—์„œ ์ตœ๋Œ€ 100๋…„์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ CryptoKey.rotationPeriod๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
    • NEXT_ROTATION_TIME: ์ฒซ ๋ฒˆ์งธ ์ˆœํ™˜์„ ์™„๋ฃŒํ•  ํƒ€์ž„์Šคํƒฌํ”„์ž…๋‹ˆ๋‹ค(์˜ˆ: 2023-01-01T01:02:03). ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์‹œ์ ์œผ๋กœ๋ถ€ํ„ฐ ํ•˜๋‚˜์˜ ์ˆœํ™˜ ๊ธฐ๊ฐ„ ๋™์•ˆ ์ฒซ ๋ฒˆ์งธ ์ˆœํ™˜์„ ์˜ˆ์•ฝํ•˜๋ ค๋ฉด --next-rotation-time์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ CryptoKey.nextRotationTime์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ๋ชจ๋“  ํ”Œ๋ž˜๊ทธ ๋ฐ ๊ฐ€๋Šฅํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด --help ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

    C#

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € C# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS C# SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    
    using Google.Cloud.Kms.V1;
    using Google.Protobuf.WellKnownTypes;
    using System;
    
    public class CreateKeyRotationScheduleSample
    {
        public CryptoKey CreateKeyRotationSchedule(
          string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring",
          string id = "my-key-with-rotation-schedule")
        {
            // Create the client.
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
    
            // Build the parent key ring name.
            KeyRingName keyRingName = new KeyRingName(projectId, locationId, keyRingId);
    
            // Build the key.
            CryptoKey key = new CryptoKey
            {
                Purpose = CryptoKey.Types.CryptoKeyPurpose.EncryptDecrypt,
                VersionTemplate = new CryptoKeyVersionTemplate
                {
                    Algorithm = CryptoKeyVersion.Types.CryptoKeyVersionAlgorithm.GoogleSymmetricEncryption,
                },
    
                // Rotate the key every 30 days.
                RotationPeriod = new Duration
                {
                    Seconds = 60 * 60 * 24 * 30, // 30 days
                },
    
                // Start the first rotation in 24 hours.
                NextRotationTime = new Timestamp
                {
                    Seconds = new DateTimeOffset(DateTime.UtcNow.AddHours(24)).ToUnixTimeSeconds(),
                }
            };
    
            // Call the API.
            CryptoKey result = client.CreateCryptoKey(keyRingName, id, key);
    
            // Return the result.
            return result;
        }
    }

    Go

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Go ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Go SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import (
    	"context"
    	"fmt"
    	"io"
    	"time"
    
    	kms "cloud.google.com/go/kms/apiv1"
    	"cloud.google.com/go/kms/apiv1/kmspb"
    	"google.golang.org/protobuf/types/known/durationpb"
    	"google.golang.org/protobuf/types/known/timestamppb"
    )
    
    // createKeyRotationSchedule creates a key with a rotation schedule.
    func createKeyRotationSchedule(w io.Writer, parent, id string) error {
    	// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring"
    	// id := "my-key-with-rotation-schedule"
    
    	// 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_ENCRYPT_DECRYPT,
    			VersionTemplate: &kmspb.CryptoKeyVersionTemplate{
    				Algorithm: kmspb.CryptoKeyVersion_GOOGLE_SYMMETRIC_ENCRYPTION,
    			},
    
    			// Rotate the key every 30 days
    			RotationSchedule: &kmspb.CryptoKey_RotationPeriod{
    				RotationPeriod: &durationpb.Duration{
    					Seconds: int64(60 * 60 * 24 * 30), // 30 days
    				},
    			},
    
    			// Start the first rotation in 24 hours
    			NextRotationTime: &timestamppb.Timestamp{
    				Seconds: time.Now().Add(24 * time.Hour).Unix(),
    			},
    		},
    	}
    
    	// 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

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € ์ž๋ฐ” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS ์ž๋ฐ” SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    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.protobuf.Duration;
    import com.google.protobuf.Timestamp;
    import java.io.IOException;
    import java.time.temporal.ChronoUnit;
    
    public class CreateKeyRotationSchedule {
    
      public void createKeyRotationSchedule() 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-key";
        createKeyRotationSchedule(projectId, locationId, keyRingId, id);
      }
    
      // Create a new key that automatically rotates on a schedule.
      public void createKeyRotationSchedule(
          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);
    
          // Calculate the date 24 hours from now (this is used below).
          long tomorrow = java.time.Instant.now().plus(24, ChronoUnit.HOURS).getEpochSecond();
    
          // Build the key to create with a rotation schedule.
          CryptoKey key =
              CryptoKey.newBuilder()
                  .setPurpose(CryptoKeyPurpose.ENCRYPT_DECRYPT)
                  .setVersionTemplate(
                      CryptoKeyVersionTemplate.newBuilder()
                          .setAlgorithm(CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION))
    
                  // Rotate every 30 days.
                  .setRotationPeriod(
                      Duration.newBuilder().setSeconds(java.time.Duration.ofDays(30).getSeconds()))
    
                  // Start the first rotation in 24 hours.
                  .setNextRotationTime(Timestamp.newBuilder().setSeconds(tomorrow))
                  .build();
    
          // Create the key.
          CryptoKey createdKey = client.createCryptoKey(keyRingName, id, key);
          System.out.printf("Created key with rotation schedule %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-rotating-encryption-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 createKeyRotationSchedule() {
      const [key] = await client.createCryptoKey({
        parent: keyRingName,
        cryptoKeyId: id,
        cryptoKey: {
          purpose: 'ENCRYPT_DECRYPT',
          versionTemplate: {
            algorithm: 'GOOGLE_SYMMETRIC_ENCRYPTION',
          },
    
          // Rotate the key every 30 days.
          rotationPeriod: {
            seconds: 60 * 60 * 24 * 30,
          },
    
          // Start the first rotation in 24 hours.
          nextRotationTime: {
            seconds: new Date().getTime() / 1000 + 60 * 60 * 24,
          },
        },
      });
    
      console.log(`Created rotating key: ${key.name}`);
      return key;
    }
    
    return createKeyRotationSchedule();

    PHP

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Google Cloud์—์„œ PHP ์‚ฌ์šฉ์— ๊ด€ํ•ด ์•Œ์•„๋ณด๊ณ  Cloud KMS PHP SDK๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”.

    use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
    use Google\Cloud\Kms\V1\CreateCryptoKeyRequest;
    use Google\Cloud\Kms\V1\CryptoKey;
    use Google\Cloud\Kms\V1\CryptoKey\CryptoKeyPurpose;
    use Google\Cloud\Kms\V1\CryptoKeyVersion\CryptoKeyVersionAlgorithm;
    use Google\Cloud\Kms\V1\CryptoKeyVersionTemplate;
    use Google\Protobuf\Duration;
    use Google\Protobuf\Timestamp;
    
    function create_key_rotation_schedule(
        string $projectId = 'my-project',
        string $locationId = 'us-east1',
        string $keyRingId = 'my-key-ring',
        string $id = 'my-key-with-rotation-schedule'
    ): CryptoKey {
        // Create the Cloud KMS client.
        $client = new KeyManagementServiceClient();
    
        // Build the parent key ring name.
        $keyRingName = $client->keyRingName($projectId, $locationId, $keyRingId);
    
        // Build the key.
        $key = (new CryptoKey())
            ->setPurpose(CryptoKeyPurpose::ENCRYPT_DECRYPT)
            ->setVersionTemplate((new CryptoKeyVersionTemplate())
                ->setAlgorithm(CryptoKeyVersionAlgorithm::GOOGLE_SYMMETRIC_ENCRYPTION))
    
            // Rotate the key every 30 days.
            ->setRotationPeriod((new Duration())
                ->setSeconds(60 * 60 * 24 * 30)
            )
    
            // Start the first rotation in 24 hours.
            ->setNextRotationTime((new Timestamp())
                ->setSeconds(time() + 60 * 60 * 24)
            );
    
        // Call the API.
        $createCryptoKeyRequest = (new CreateCryptoKeyRequest())
            ->setParent($keyRingName)
            ->setCryptoKeyId($id)
            ->setCryptoKey($key);
        $createdKey = $client->createCryptoKey($createCryptoKeyRequest);
        printf('Created key with rotation: %s' . PHP_EOL, $createdKey->getName());
    
        return $createdKey;
    }

    Python

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Python SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import time
    
    from google.cloud import kms
    
    
    def create_key_rotation_schedule(
        project_id: str, location_id: str, key_ring_id: str, key_id: str
    ) -> kms.CryptoKey:
        """
        Creates a new key in Cloud KMS that automatically rotates.
    
        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').
            key_id (string): ID of the key to create (e.g. 'my-rotating-key').
    
        Returns:
            CryptoKey: Cloud KMS key.
    
        """
    
        # Create the client.
        client = kms.KeyManagementServiceClient()
    
        # Build the parent key ring name.
        key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)
    
        # Build the key.
        purpose = kms.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT
        algorithm = (
            kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION
        )
        key = {
            "purpose": purpose,
            "version_template": {
                "algorithm": algorithm,
            },
            # Rotate the key every 30 days.
            "rotation_period": {"seconds": 60 * 60 * 24 * 30},
            # Start the first rotation in 24 hours.
            "next_rotation_time": {"seconds": int(time.time()) + 60 * 60 * 24},
        }
    
        # Call the API.
        created_key = client.create_crypto_key(
            request={"parent": key_ring_name, "crypto_key_id": key_id, "crypto_key": key}
        )
        print(f"Created labeled key: {created_key.name}")
        return created_key
    
    

    Ruby

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Ruby ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Ruby SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    # TODO(developer): uncomment these values before running the sample.
    # project_id  = "my-project"
    # location_id = "us-east1"
    # key_ring_id = "my-key-ring"
    # id          = "my-key-with-rotation"
    
    # Require the library.
    require "google/cloud/kms"
    
    # Create the client.
    client = Google::Cloud::Kms.key_management_service
    
    # Build the parent key ring name.
    key_ring_name = client.key_ring_path project: project_id, location: location_id, key_ring: key_ring_id
    
    # Build the key.
    key = {
      purpose:            :ENCRYPT_DECRYPT,
      version_template:   {
        algorithm: :GOOGLE_SYMMETRIC_ENCRYPTION
      },
    
      # Rotate the key every 30 days.
      rotation_period:    {
        seconds: 60 * 60 * 24 * 30
      },
    
      # Start the first rotation in 24 hours.
      next_rotation_time: {
        seconds: (Time.now + (60 * 60 * 24)).to_i
      }
    }
    
    # Call the API.
    created_key = client.create_crypto_key parent: key_ring_name, crypto_key_id: id, crypto_key: key
    puts "Created rotating key: #{created_key.name}"

    API

    ์ด ์˜ˆ์‹œ์—์„œ๋Š” curl์„ HTTP ํด๋ผ์ด์–ธํŠธ๋กœ ์‚ฌ์šฉํ•˜์—ฌ API ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ์ œ์–ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud KMS API ์•ก์„ธ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    ํ‚ค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด CryptoKey.create ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys?crypto_key_id=KEY_NAME" \
        --request "POST" \
        --header "authorization: Bearer TOKEN" \
        --header "content-type: application/json" \
        --data '{"purpose": "PURPOSE", "rotationPeriod": "ROTATION_PERIOD", "nextRotationTime": "NEXT_ROTATION_TIME"}'
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PURPOSE: ํ‚ค์˜ ์šฉ๋„์ž…๋‹ˆ๋‹ค.
    • ROTATION_PERIOD: ํ‚ค๋ฅผ ์ˆœํ™˜ํ•˜๋Š” ๊ฐ„๊ฒฉ์ž…๋‹ˆ๋‹ค(์˜ˆ: 30d๋Š” ํ‚ค๋ฅผ 30์ผ๋งˆ๋‹ค ์ˆœํ™˜). ์ˆœํ™˜ ๊ธฐ๊ฐ„์€ ์ตœ์†Œ 1์ผ์—์„œ ์ตœ๋Œ€ 100๋…„์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ CryptoKey.rotationPeriod๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
    • NEXT_ROTATION_TIME: ์ฒซ ๋ฒˆ์งธ ์ˆœํ™˜์„ ์™„๋ฃŒํ•  ํƒ€์ž„์Šคํƒฌํ”„์ž…๋‹ˆ๋‹ค(์˜ˆ: 2023-01-01T01:02:03). ์ž์„ธํ•œ ๋‚ด์šฉ์€ CryptoKey.nextRotationTime์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    'ํ๊ธฐ ์˜ˆ์•ฝ๋จ' ์ƒํƒœ ์œ ์ง€ ๊ธฐ๊ฐ„ ์„ค์ •

    ๊ธฐ๋ณธ์ ์œผ๋กœ Cloud KMS์˜ ํ‚ค ๋ฒ„์ „์€ ํ๊ธฐ๋˜๊ธฐ ์ „ 30์ผ ๋™์•ˆ ํ๊ธฐ ์˜ˆ์•ฝ๋จ(DESTROY_SCHEDULED) ์ƒํƒœ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ํ๊ธฐ ์˜ˆ์•ฝ๋จ ์ƒํƒœ๋ฅผ ์†Œํ”„ํŠธ ์‚ญ์ œ ์ƒํƒœ๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค. ํ‚ค ๋ฒ„์ „์ด ์ด ์ƒํƒœ๋กœ ์œ ์ง€๋˜๋Š” ๊ธฐ๊ฐ„์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ œ์•ฝ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

    • ํ‚ค๋ฅผ ๋งŒ๋“œ๋Š” ๋„์ค‘์—๋งŒ ๊ธฐ๊ฐ„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ํ‚ค ๊ธฐ๊ฐ„์ด ์ง€์ •๋œ ํ›„์—๋Š” ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    • ๊ธฐ๊ฐ„์€ ์ดํ›„์— ์ƒ์„ฑ๋˜๋Š” ๋ชจ๋“  ํ‚ค ๋ฒ„์ „์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • ์ตœ์†Œ ๊ธฐ๊ฐ„์€ ๋ชจ๋“  ํ‚ค์— ๋Œ€ํ•ด 24์‹œ๊ฐ„์ด๊ณ , ์ตœ์†Œ ๊ธฐ๊ฐ„์ด 0์ธ ๊ฐ€์ ธ์˜ค๊ธฐ ์ „์šฉ ํ‚ค๋Š” ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค.
    • ์ตœ๋Œ€ ๊ธฐ๊ฐ„์€ 120์ผ์ž…๋‹ˆ๋‹ค.
    • ๊ธฐ๋ณธ ๊ธฐ๊ฐ„์€ 30์ผ์ž…๋‹ˆ๋‹ค.

    ์กฐ์ง์˜ ์กฐ์ง ์ •์ฑ…์— ์ตœ์†Œ ํ๊ธฐ ์˜ˆ์•ฝ ๊ธฐ๊ฐ„ ๊ฐ’์ด ์ •์˜๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ‚ค ํ๊ธฐ ์ œ์–ด๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    ํ๊ธฐ ์˜ˆ์•ฝ ์ƒํƒœ์— ๋Œ€ํ•ด ๋งž์ถค ๊ธฐ๊ฐ„์„ ์‚ฌ์šฉํ•˜๋Š” ํ‚ค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

    ์ฝ˜์†”

    1. Google Cloud ์ฝ˜์†”์—์„œ ํ‚ค ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

      Key Management Service๋กœ ์ด๋™

    2. ํ‚ค๋ฅผ ๋งŒ๋“ค ํ‚ค๋ง์˜ ์ด๋ฆ„์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    3. ํ‚ค ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    4. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ‚ค ์„ค์ •์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    5. ์ถ”๊ฐ€ ์„ค์ •์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    6. 'ํ๊ธฐ ์˜ˆ์•ฝ๋จ' ์ƒํƒœ ์œ ์ง€ ๊ธฐ๊ฐ„์—์„œ ์˜๊ตฌ์ ์œผ๋กœ ํ๊ธฐ๋˜๊ธฐ ์ „์— ํ‚ค๋ฅผ ํ๊ธฐ ์˜ˆ์•ฝ๋จ ์ƒํƒœ๋กœ ์œ ์ง€ํ•  ๊ธฐ๊ฐ„(์ผ)์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    7. ํ‚ค ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    gcloud

    ๋ช…๋ น์ค„์—์„œ Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์ตœ์‹  ๋ฒ„์ „์˜ Google Cloud CLI๋กœ ์„ค์น˜ ๋˜๋Š” ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”.

    gcloud kms keys create KEY_NAME \
        --keyring KEY_RING \
        --location LOCATION \
        --purpose PURPOSE \
        --destroy-scheduled-duration DURATION
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • PURPOSE: ํ‚ค์˜ ์šฉ๋„์ž…๋‹ˆ๋‹ค(์˜ˆ: encryption).
    • DURATION: ์˜๊ตฌ์ ์œผ๋กœ ํ๊ธฐํ•˜๊ธฐ ์ „์— ํ‚ค๋ฅผ ํ๊ธฐ ์˜ˆ์•ฝ๋จ ์ƒํƒœ๋กœ ์œ ์ง€ํ•  ๊ธฐ๊ฐ„์ž…๋‹ˆ๋‹ค.

    ๋ชจ๋“  ํ”Œ๋ž˜๊ทธ ๋ฐ ๊ฐ€๋Šฅํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด --help ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

    ํŠน์ • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋˜๋Š” ๊ทœ์ œ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ฐ’์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ํ•œ ๋ชจ๋“  ํ‚ค์— ๋Œ€ํ•ด ๊ธฐ๋ณธ ๊ธฐ๊ฐ„์ธ 30์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

    ๋น„๋Œ€์นญ ํ‚ค ๋งŒ๋“ค๊ธฐ

    ๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ๋น„๋Œ€์นญ ํ‚ค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

    ๋น„๋Œ€์นญ ๋ณตํ˜ธํ™” ํ‚ค ๋งŒ๋“ค๊ธฐ

    ๋‹ค์Œ ๋‹จ๊ณ„์— ๋”ฐ๋ผ ์ง€์ •๋œ ํ‚ค๋ง ๋ฐ ์œ„์น˜์— ๋น„๋Œ€์นญ ๋ณตํ˜ธํ™” ํ‚ค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜ˆ์‹œ๋ฅผ ์กฐ์ •ํ•˜์—ฌ ๋‹ค๋ฅธ ๋ณดํ˜ธ ์ˆ˜์ค€ ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ ๋ฐ ๋Œ€์ฒด ๊ฐ’์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฐ ๋ณดํ˜ธ ์ˆ˜์ค€์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ํ‚ค๋ฅผ ์ฒ˜์Œ ๋งŒ๋“ค ๋•Œ ์ดˆ๊ธฐ ํ‚ค ๋ฒ„์ „ ์ƒํƒœ๋Š” ์ƒ์„ฑ ๋Œ€๊ธฐ ์ค‘์ž…๋‹ˆ๋‹ค. ์ƒํƒœ๊ฐ€ ์‚ฌ์šฉ ์„ค์ •๋จ์œผ๋กœ ๋ฐ”๋€Œ๋ฉด ํ‚ค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ‚ค ๋ฒ„์ „ ์ƒํƒœ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ‚ค ๋ฒ„์ „ ์ƒํƒœ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    ์ฝ˜์†”

    1. Google Cloud ์ฝ˜์†”์—์„œ ํ‚ค ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

      Key Management Service๋กœ ์ด๋™

    2. ํ‚ค๋ฅผ ๋งŒ๋“ค ํ‚ค๋ง์˜ ์ด๋ฆ„์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    3. ํ‚ค ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    4. ํ‚ค ์ด๋ฆ„์— ํ‚ค์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    5. ๋ณดํ˜ธ ์ˆ˜์ค€์—์„œ ์†Œํ”„ํŠธ์›จ์–ด ๋˜๋Š” HSM์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    6. ํ‚ค ์ž๋ฃŒ์—์„œ ์ƒ์„ฑ๋œ ํ‚ค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    7. ์šฉ๋„์—์„œ ๋น„๋Œ€์นญ ๋ณตํ˜ธํ™”๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    8. ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ 3072๋น„ํŠธ RSA - OAEP ํŒจ๋”ฉ - SHA256 ๋‹ค์ด์ œ์ŠคํŠธ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ํ‚ค ๋ฒ„์ „์—์„œ ์ด ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    9. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    gcloud

    ๋ช…๋ น์ค„์—์„œ Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์ตœ์‹  ๋ฒ„์ „์˜ Google Cloud CLI๋กœ ์„ค์น˜ ๋˜๋Š” ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”.

    gcloud kms keys create KEY_NAME \
        --keyring KEY_RING \
        --location LOCATION \
        --purpose "asymmetric-encryption" \
        --default-algorithm "ALGORITHM"
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • ALGORITHM: ํ‚ค์— ์‚ฌ์šฉํ•  ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค(์˜ˆ: rsa-decrypt-oaep-3072-sha256). ์ง€์›๋˜๋Š” ๋น„๋Œ€์นญ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ชฉ๋ก์€ ๋น„๋Œ€์นญ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ๋ชจ๋“  ํ”Œ๋ž˜๊ทธ ๋ฐ ๊ฐ€๋Šฅํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด --help ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

    C#

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € C# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS C# SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    
    using Google.Cloud.Kms.V1;
    using Google.Protobuf.WellKnownTypes;
    
    public class CreateKeyAsymmetricDecryptSample
    {
        public CryptoKey CreateKeyAsymmetricDecrypt(
          string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring",
          string id = "my-asymmetric-encrypt-key")
        {
            // Create the client.
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
    
            // Build the parent key ring name.
            KeyRingName keyRingName = new KeyRingName(projectId, locationId, keyRingId);
    
            // Build the key.
            CryptoKey key = new CryptoKey
            {
                Purpose = CryptoKey.Types.CryptoKeyPurpose.AsymmetricDecrypt,
                VersionTemplate = new CryptoKeyVersionTemplate
                {
                    Algorithm = CryptoKeyVersion.Types.CryptoKeyVersionAlgorithm.RsaDecryptOaep2048Sha256,
                },
    
                // Optional: customize how long key versions should be kept before destroying.
                DestroyScheduledDuration = new Duration
                {
                    Seconds = 24 * 60 * 60,
                }
            };
    
            // Call the API.
            CryptoKey result = client.CreateCryptoKey(keyRingName, id, key);
    
            // Return the result.
            return result;
        }
    }

    Go

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Go ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Go SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import (
    	"context"
    	"fmt"
    	"io"
    	"time"
    
    	kms "cloud.google.com/go/kms/apiv1"
    	"cloud.google.com/go/kms/apiv1/kmspb"
    	"google.golang.org/protobuf/types/known/durationpb"
    )
    
    // createKeyAsymmetricDecrypt creates a new asymmetric RSA encrypt/decrypt key
    // pair where the private key is stored in Cloud KMS.
    func createKeyAsymmetricDecrypt(w io.Writer, parent, id string) error {
    	// parent := "projects/my-project/locations/us-east1/keyRings/my-key-ring"
    	// id := "my-asymmetric-encryption-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_DECRYPT,
    			VersionTemplate: &kmspb.CryptoKeyVersionTemplate{
    				Algorithm: kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_2048_SHA256,
    			},
    
    			// Optional: customize how long key versions should be kept before destroying.
    			DestroyScheduledDuration: durationpb.New(24 * time.Hour),
    		},
    	}
    
    	// 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

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € ์ž๋ฐ” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS ์ž๋ฐ” SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    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.protobuf.Duration;
    import java.io.IOException;
    
    public class CreateKeyAsymmetricDecrypt {
    
      public void createKeyAsymmetricDecrypt() 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-asymmetric-decryption-key";
        createKeyAsymmetricDecrypt(projectId, locationId, keyRingId, id);
      }
    
      // Create a new asymmetric key for the purpose of encrypting and decrypting
      // data.
      public void createKeyAsymmetricDecrypt(
          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);
    
          // Build the asymmetric key to create.
          CryptoKey key =
              CryptoKey.newBuilder()
                  .setPurpose(CryptoKeyPurpose.ASYMMETRIC_DECRYPT)
                  .setVersionTemplate(
                      CryptoKeyVersionTemplate.newBuilder()
                          .setAlgorithm(CryptoKeyVersionAlgorithm.RSA_DECRYPT_OAEP_2048_SHA256))
    
                  // Optional: customize how long key versions should be kept before destroying.
                  .setDestroyScheduledDuration(Duration.newBuilder().setSeconds(24 * 60 * 60))
                  .build();
    
          // Create the key.
          CryptoKey createdKey = client.createCryptoKey(keyRingName, id, key);
          System.out.printf("Created asymmetric 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-asymmetric-decrypt-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 createKeyAsymmetricDecrypt() {
      const [key] = await client.createCryptoKey({
        parent: keyRingName,
        cryptoKeyId: id,
        cryptoKey: {
          purpose: 'ASYMMETRIC_DECRYPT',
          versionTemplate: {
            algorithm: 'RSA_DECRYPT_OAEP_2048_SHA256',
          },
    
          // Optional: customize how long key versions should be kept before
          // destroying.
          destroyScheduledDuration: {seconds: 60 * 60 * 24},
        },
      });
    
      console.log(`Created asymmetric key: ${key.name}`);
      return key;
    }
    
    return createKeyAsymmetricDecrypt();

    PHP

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Google Cloud์—์„œ PHP ์‚ฌ์šฉ์— ๊ด€ํ•ด ์•Œ์•„๋ณด๊ณ  Cloud KMS PHP SDK๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”.

    use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
    use Google\Cloud\Kms\V1\CreateCryptoKeyRequest;
    use Google\Cloud\Kms\V1\CryptoKey;
    use Google\Cloud\Kms\V1\CryptoKey\CryptoKeyPurpose;
    use Google\Cloud\Kms\V1\CryptoKeyVersion\CryptoKeyVersionAlgorithm;
    use Google\Cloud\Kms\V1\CryptoKeyVersionTemplate;
    use Google\Protobuf\Duration;
    
    function create_key_asymmetric_decrypt(
        string $projectId = 'my-project',
        string $locationId = 'us-east1',
        string $keyRingId = 'my-key-ring',
        string $id = 'my-asymmetric-decrypt-key'
    ): CryptoKey {
        // Create the Cloud KMS client.
        $client = new KeyManagementServiceClient();
    
        // Build the parent key ring name.
        $keyRingName = $client->keyRingName($projectId, $locationId, $keyRingId);
    
        // Build the key.
        $key = (new CryptoKey())
            ->setPurpose(CryptoKeyPurpose::ASYMMETRIC_DECRYPT)
            ->setVersionTemplate((new CryptoKeyVersionTemplate())
                ->setAlgorithm(CryptoKeyVersionAlgorithm::RSA_DECRYPT_OAEP_2048_SHA256)
            )
    
            // Optional: customize how long key versions should be kept before destroying.
            ->setDestroyScheduledDuration((new Duration())
                ->setSeconds(24 * 60 * 60)
            );
    
        // Call the API.
        $createCryptoKeyRequest = (new CreateCryptoKeyRequest())
            ->setParent($keyRingName)
            ->setCryptoKeyId($id)
            ->setCryptoKey($key);
        $createdKey = $client->createCryptoKey($createCryptoKeyRequest);
        printf('Created asymmetric decryption key: %s' . PHP_EOL, $createdKey->getName());
    
        return $createdKey;
    }

    Python

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Python SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import datetime
    
    # Import the client library.
    from google.cloud import kms
    from google.protobuf import duration_pb2  # type: ignore
    
    
    def create_key_asymmetric_decrypt(
        project_id: str, location_id: str, key_ring_id: str, key_id: str
    ) -> kms.CryptoKey:
        """
        Creates a new asymmetric decryption key in Cloud KMS.
    
        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').
            key_id (string): ID of the key to create (e.g. 'my-asymmetric-decrypt-key').
    
        Returns:
            CryptoKey: Cloud KMS key.
    
        """
    
        # Create the client.
        client = kms.KeyManagementServiceClient()
    
        # Build the parent key ring name.
        key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)
    
        # Build the key.
        purpose = kms.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_DECRYPT
        algorithm = (
            kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.RSA_DECRYPT_OAEP_2048_SHA256
        )
        key = {
            "purpose": purpose,
            "version_template": {
                "algorithm": algorithm,
            },
            # Optional: customize how long key versions should be kept before
            # destroying.
            "destroy_scheduled_duration": duration_pb2.Duration().FromTimedelta(
                datetime.timedelta(days=1)
            ),
        }
    
        # Call the API.
        created_key = client.create_crypto_key(
            request={"parent": key_ring_name, "crypto_key_id": key_id, "crypto_key": key}
        )
        print(f"Created asymmetric decrypt key: {created_key.name}")
        return created_key
    
    

    Ruby

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Ruby ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Ruby SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    # TODO(developer): uncomment these values before running the sample.
    # project_id  = "my-project"
    # location_id = "us-east1"
    # key_ring_id = "my-key-ring"
    # id          = "my-asymmetric-decrypt-key"
    
    # Require the library.
    require "google/cloud/kms"
    
    # Create the client.
    client = Google::Cloud::Kms.key_management_service
    
    # Build the parent key ring name.
    key_ring_name = client.key_ring_path project: project_id, location: location_id, key_ring: key_ring_id
    
    # Build the key.
    key = {
      purpose:          :ASYMMETRIC_DECRYPT,
      version_template: {
        algorithm: :RSA_DECRYPT_OAEP_2048_SHA256
      },
    
      # Optional: customize how long key versions should be kept before destroying.
      destroy_scheduled_duration: {
        seconds: 24 * 60 * 60
      }
    }
    
    # Call the API.
    created_key = client.create_crypto_key parent: key_ring_name, crypto_key_id: id, crypto_key: key
    puts "Created asymmetric decryption key: #{created_key.name}"

    API

    ์ด ์˜ˆ์‹œ์—์„œ๋Š” curl์„ HTTP ํด๋ผ์ด์–ธํŠธ๋กœ ์‚ฌ์šฉํ•˜์—ฌ API ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ์ œ์–ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud KMS API ์•ก์„ธ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    CryptoKey.create๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„๋Œ€์นญ ๋ณตํ˜ธํ™” ํ‚ค๋ฅผ ๋งŒ๋“œ์„ธ์š”.

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys?crypto_key_id=KEY_NAME" \
        --request "POST" \
        --header "authorization: Bearer TOKEN" \
        --header "content-type: application/json" \
        --data '{"purpose": "ASYMMETRIC_DECRYPT", "versionTemplate": {"algorithm": "ALGORITHM"}}'
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: ํ‚ค๋ง์ด ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ID์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • ALGORITHM: ํ‚ค์— ์‚ฌ์šฉํ•  ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค(์˜ˆ: RSA_DECRYPT_OAEP_3072_SHA256). ์ง€์›๋˜๋Š” ๋น„๋Œ€์นญ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ชฉ๋ก์€ ๋น„๋Œ€์นญ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ๋น„๋Œ€์นญ ์„œ๋ช… ํ‚ค ๋งŒ๋“ค๊ธฐ

    ๋‹ค์Œ ๋‹จ๊ณ„์— ๋”ฐ๋ผ ์ง€์ •๋œ ํ‚ค๋ง ๋ฐ ์œ„์น˜์— ๋น„๋Œ€์นญ ์„œ๋ช… ํ‚ค๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜ˆ์‹œ๋ฅผ ์กฐ์ •ํ•˜์—ฌ ๋‹ค๋ฅธ ๋ณดํ˜ธ ์ˆ˜์ค€ ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ ๋ฐ ๋Œ€์ฒด ๊ฐ’์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฐ ๋ณดํ˜ธ ์ˆ˜์ค€์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ํ‚ค๋ฅผ ์ฒ˜์Œ ๋งŒ๋“ค ๋•Œ ์ดˆ๊ธฐ ํ‚ค ๋ฒ„์ „ ์ƒํƒœ๋Š” ์ƒ์„ฑ ๋Œ€๊ธฐ ์ค‘์ž…๋‹ˆ๋‹ค. ์ƒํƒœ๊ฐ€ ์‚ฌ์šฉ ์„ค์ •๋จ์œผ๋กœ ๋ฐ”๋€Œ๋ฉด ํ‚ค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ‚ค ๋ฒ„์ „ ์ƒํƒœ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ‚ค ๋ฒ„์ „ ์ƒํƒœ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    ์ฝ˜์†”

    1. Google Cloud ์ฝ˜์†”์—์„œ ํ‚ค ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

      Key Management Service๋กœ ์ด๋™

    2. ํ‚ค๋ฅผ ๋งŒ๋“ค ํ‚ค๋ง์˜ ์ด๋ฆ„์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    3. ํ‚ค ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    4. ํ‚ค ์ด๋ฆ„์— ํ‚ค์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    5. ๋ณดํ˜ธ ์ˆ˜์ค€์—์„œ ์†Œํ”„ํŠธ์›จ์–ด ๋˜๋Š” HSM์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    6. ํ‚ค ์ž๋ฃŒ์—์„œ ์ƒ์„ฑ๋œ ํ‚ค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    7. ์šฉ๋„์—์„œ ๋น„๋Œ€์นญ ์„œ๋ช…์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    8. ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ํƒ€์› ๊ณก์„  P-256 - SHA256 ๋‹ค์ด์ œ์ŠคํŠธ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ํ‚ค ๋ฒ„์ „์—์„œ ์ด ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    9. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    gcloud

    ๋ช…๋ น์ค„์—์„œ Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์ตœ์‹  ๋ฒ„์ „์˜ Google Cloud CLI๋กœ ์„ค์น˜ ๋˜๋Š” ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”.

    gcloud kms keys create KEY_NAME \
        --keyring KEY_RING \
        --location LOCATION \
        --purpose "asymmetric-signing" \
        --default-algorithm "ALGORITHM"
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • ALGORITHM: ํ‚ค์— ์‚ฌ์šฉํ•  ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค(์˜ˆ: ec-sign-p256-sha256). ์ง€์›๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ชฉ๋ก์€ ๋น„๋Œ€์นญ ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ๋ชจ๋“  ํ”Œ๋ž˜๊ทธ ๋ฐ ๊ฐ€๋Šฅํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด --help ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

    C#

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € C# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS C# SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    
    using Google.Cloud.Kms.V1;
    using Google.Protobuf.WellKnownTypes;
    
    public class CreateKeyAsymmetricSignSample
    {
        public CryptoKey CreateKeyAsymmetricSign(
          string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring",
          string id = "my-asymmetric-signing-key")
        {
            // Create the client.
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
    
            // Build the parent key ring name.
            KeyRingName keyRingName = new KeyRingName(projectId, locationId, keyRingId);
    
            // Build the key.
            CryptoKey key = new CryptoKey
            {
                Purpose = CryptoKey.Types.CryptoKeyPurpose.AsymmetricSign,
                VersionTemplate = new CryptoKeyVersionTemplate
                {
                    Algorithm = CryptoKeyVersion.Types.CryptoKeyVersionAlgorithm.RsaSignPkcs12048Sha256,
                },
    
                // Optional: customize how long key versions should be kept before destroying.
                DestroyScheduledDuration = new Duration
                {
                    Seconds = 24 * 60 * 60,
                }
            };
    
            // Call the API.
            CryptoKey result = client.CreateCryptoKey(keyRingName, id, key);
    
            // Return the result.
            return result;
        }
    }

    Go

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Go ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Go SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import (
    	"context"
    	"fmt"
    	"io"
    	"time"
    
    	kms "cloud.google.com/go/kms/apiv1"
    	"cloud.google.com/go/kms/apiv1/kmspb"
    	"google.golang.org/protobuf/types/known/durationpb"
    )
    
    // createKeyAsymmetricSign creates a new asymmetric RSA sign/verify key pair
    // where the private key is stored in Cloud KMS.
    func createKeyAsymmetricSign(w io.Writer, parent, id string) error {
    	// parent := "projects/my-project/locations/us-east1/keyRings/my-key-ring"
    	// id := "my-asymmetric-signing-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{
    				Algorithm: kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_2048_SHA256,
    			},
    
    			// Optional: customize how long key versions should be kept before destroying.
    			DestroyScheduledDuration: durationpb.New(24 * time.Hour),
    		},
    	}
    
    	// 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

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € ์ž๋ฐ” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS ์ž๋ฐ” SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    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.protobuf.Duration;
    import java.io.IOException;
    
    public class CreateKeyAsymmetricSign {
    
      public void createKeyAsymmetricSign() 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-asymmetric-signing-key";
        createKeyAsymmetricSign(projectId, locationId, keyRingId, id);
      }
    
      // Create a new asymmetric key for the purpose of signing and verifying data.
      public void createKeyAsymmetricSign(
          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);
    
          // Build the asymmetric key to create.
          CryptoKey key =
              CryptoKey.newBuilder()
                  .setPurpose(CryptoKeyPurpose.ASYMMETRIC_SIGN)
                  .setVersionTemplate(
                      CryptoKeyVersionTemplate.newBuilder()
                          .setAlgorithm(CryptoKeyVersionAlgorithm.RSA_SIGN_PKCS1_2048_SHA256))
    
                  // Optional: customize how long key versions should be kept before destroying.
                  .setDestroyScheduledDuration(Duration.newBuilder().setSeconds(24 * 60 * 60))
                  .build();
    
          // Create the key.
          CryptoKey createdKey = client.createCryptoKey(keyRingName, id, key);
          System.out.printf("Created asymmetric 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-asymmetric-sign-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 createKeyAsymmetricSign() {
      const [key] = await client.createCryptoKey({
        parent: keyRingName,
        cryptoKeyId: id,
        cryptoKey: {
          purpose: 'ASYMMETRIC_SIGN',
          versionTemplate: {
            algorithm: 'RSA_SIGN_PKCS1_2048_SHA256',
          },
    
          // Optional: customize how long key versions should be kept before
          // destroying.
          destroyScheduledDuration: {seconds: 60 * 60 * 24},
        },
      });
    
      console.log(`Created asymmetric key: ${key.name}`);
      return key;
    }
    
    return createKeyAsymmetricSign();

    PHP

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Google Cloud์—์„œ PHP ์‚ฌ์šฉ์— ๊ด€ํ•ด ์•Œ์•„๋ณด๊ณ  Cloud KMS PHP SDK๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”.

    use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
    use Google\Cloud\Kms\V1\CreateCryptoKeyRequest;
    use Google\Cloud\Kms\V1\CryptoKey;
    use Google\Cloud\Kms\V1\CryptoKey\CryptoKeyPurpose;
    use Google\Cloud\Kms\V1\CryptoKeyVersion\CryptoKeyVersionAlgorithm;
    use Google\Cloud\Kms\V1\CryptoKeyVersionTemplate;
    use Google\Protobuf\Duration;
    
    function create_key_asymmetric_sign(
        string $projectId = 'my-project',
        string $locationId = 'us-east1',
        string $keyRingId = 'my-key-ring',
        string $id = 'my-asymmetric-signing-key'
    ): CryptoKey {
        // Create the Cloud KMS client.
        $client = new KeyManagementServiceClient();
    
        // Build the parent key ring name.
        $keyRingName = $client->keyRingName($projectId, $locationId, $keyRingId);
    
        // Build the key.
        $key = (new CryptoKey())
            ->setPurpose(CryptoKeyPurpose::ASYMMETRIC_SIGN)
            ->setVersionTemplate((new CryptoKeyVersionTemplate())
                ->setAlgorithm(CryptoKeyVersionAlgorithm::RSA_SIGN_PKCS1_2048_SHA256)
            )
    
            // Optional: customize how long key versions should be kept before destroying.
            ->setDestroyScheduledDuration((new Duration())
                ->setSeconds(24 * 60 * 60)
            );
    
        // Call the API.
        $createCryptoKeyRequest = (new CreateCryptoKeyRequest())
            ->setParent($keyRingName)
            ->setCryptoKeyId($id)
            ->setCryptoKey($key);
        $createdKey = $client->createCryptoKey($createCryptoKeyRequest);
        printf('Created asymmetric signing key: %s' . PHP_EOL, $createdKey->getName());
    
        return $createdKey;
    }

    Python

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Python SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    
    import datetime
    
    # Import the client library.
    from google.cloud import kms
    from google.protobuf import duration_pb2  # type: ignore
    
    
    def create_key_asymmetric_sign(
        project_id: str, location_id: str, key_ring_id: str, key_id: str
    ) -> kms.CryptoKey:
        """
        Creates a new asymmetric signing key in Cloud KMS.
    
        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').
            key_id (string): ID of the key to create (e.g. 'my-asymmetric-signing-key').
    
        Returns:
            CryptoKey: Cloud KMS key.
    
        """
    
        # Create the client.
        client = kms.KeyManagementServiceClient()
    
        # Build the parent key ring name.
        key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)
    
        # Build the key.
        purpose = kms.CryptoKey.CryptoKeyPurpose.ASYMMETRIC_SIGN
        algorithm = (
            kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.RSA_SIGN_PKCS1_2048_SHA256
        )
        key = {
            "purpose": purpose,
            "version_template": {
                "algorithm": algorithm,
            },
            # Optional: customize how long key versions should be kept before
            # destroying.
            "destroy_scheduled_duration": duration_pb2.Duration().FromTimedelta(
                datetime.timedelta(days=1)
            ),
        }
    
        # Call the API.
        created_key = client.create_crypto_key(
            request={"parent": key_ring_name, "crypto_key_id": key_id, "crypto_key": key}
        )
        print(f"Created asymmetric signing key: {created_key.name}")
        return created_key
    
    

    Ruby

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Ruby ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Ruby SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    # TODO(developer): uncomment these values before running the sample.
    # project_id  = "my-project"
    # location_id = "us-east1"
    # key_ring_id = "my-key-ring"
    # id          = "my-asymmetric-signing-key"
    
    # Require the library.
    require "google/cloud/kms"
    
    # Create the client.
    client = Google::Cloud::Kms.key_management_service
    
    # Build the parent key ring name.
    key_ring_name = client.key_ring_path project: project_id, location: location_id, key_ring: key_ring_id
    
    # Build the key.
    key = {
      purpose:          :ASYMMETRIC_SIGN,
      version_template: {
        algorithm: :RSA_SIGN_PKCS1_2048_SHA256
      },
    
      # Optional: customize how long key versions should be kept before destroying.
      destroy_scheduled_duration: {
        seconds: 24 * 60 * 60
      }
    }
    
    # Call the API.
    created_key = client.create_crypto_key parent: key_ring_name, crypto_key_id: id, crypto_key: key
    puts "Created asymmetric signing key: #{created_key.name}"

    API

    ์ด ์˜ˆ์‹œ์—์„œ๋Š” curl์„ HTTP ํด๋ผ์ด์–ธํŠธ๋กœ ์‚ฌ์šฉํ•˜์—ฌ API ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ์ œ์–ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud KMS API ์•ก์„ธ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    CryptoKey.create๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„๋Œ€์นญ ์„œ๋ช… ํ‚ค๋ฅผ ๋งŒ๋“œ์„ธ์š”.

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys?crypto_key_id=KEY_NAME" \
        --request "POST" \
        --header "authorization: Bearer TOKEN" \
        --header "content-type: application/json" \
        --data '{"purpose": "ASYMMETRIC_SIGN", "versionTemplate": {"algorithm": "ALGORITHM"}}'
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: ํ‚ค๋ง์ด ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ID์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • ALGORITHM: ํ‚ค์— ์‚ฌ์šฉํ•  ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค(์˜ˆ: EC_SIGN_P256_SHA256). ์ง€์›๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ชฉ๋ก์€ ๋น„๋Œ€์นญ ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ๊ณต๊ฐœ ํ‚ค ๊ฐ€์ ธ์˜ค๊ธฐ

    ๋น„๋Œ€์นญ ํ‚ค๋ฅผ ๋งŒ๋“ค๋ฉด Cloud KMS์—์„œ ๊ณต๊ฐœ ํ‚ค/๋น„๊ณต๊ฐœ ํ‚ค ์Œ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํ‚ค๊ฐ€ ์ƒ์„ฑ๋œ ํ›„ ์–ธ์ œ๋“ ์ง€ ์‚ฌ์šฉ ์„ค์ •๋œ ๋น„๋Œ€์นญ ํ‚ค์˜ ๊ณต๊ฐœ ํ‚ค๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๊ณต๊ฐœ ํ‚ค๋Š” PEM(Privacy-enhanced Electronic Mail) ํ˜•์‹์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ RFC 7468 ์„น์…˜ ์ผ๋ฐ˜ ๊ณ ๋ ค์‚ฌํ•ญ ๋ฐ ๋Œ€์ƒ ๊ณต๊ฐœ ํ‚ค ์ •๋ณด์˜ ํ…์ŠคํŠธ ์ธ์ฝ”๋”ฉ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ๊ธฐ์กด ๋น„๋Œ€์นญ ํ‚ค ๋ฒ„์ „์˜ ๊ณต๊ฐœ ํ‚ค๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

    ์ฝ˜์†”

    1. Google Cloud ์ฝ˜์†”์—์„œ ํ‚ค ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

      Key Management Service๋กœ ์ด๋™

    2. ๊ณต๊ฐœ ํ‚ค๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋น„๋Œ€์นญ ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    3. ๊ณต๊ฐœ ํ‚ค๋ฅผ ๊ฐ€์ ธ์˜ฌ ํ‚ค์˜ ์ด๋ฆ„์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    4. ๊ณต๊ฐœ ํ‚ค๋ฅผ ๊ฒ€์ƒ‰ํ•  ํ‚ค ๋ฒ„์ „์— ํ•ด๋‹นํ•˜๋Š” ํ–‰์—์„œ ๋”๋ณด๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    5. ๊ณต๊ฐœ ํ‚ค ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    6. ๊ณต๊ฐœ ํ‚ค๊ฐ€ ํ”„๋กฌํ”„ํŠธ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๊ณต๊ฐœ ํ‚ค๋ฅผ ํด๋ฆฝ๋ณด๋“œ์— ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต๊ฐœ ํ‚ค๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๋ ค๋ฉด ๋‹ค์šด๋กœ๋“œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    ๊ณต๊ฐœ ํ‚ค ๊ฐ€์ ธ์˜ค๊ธฐ ์˜ต์…˜์ด ํ‘œ์‹œ๋˜์ง€ ์•Š์œผ๋ฉด ๋‹ค์Œ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    • ํ‚ค๊ฐ€ ๋น„๋Œ€์นญ ํ‚ค์ž…๋‹ˆ๋‹ค.
    • ํ‚ค ๋ฒ„์ „์ด ์‚ฌ์šฉ ์„ค์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
    • cloudkms.cryptoKeyVersions.viewPublicKey ๊ถŒํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

    Google Cloud ์ฝ˜์†”์—์„œ ๋‹ค์šด๋กœ๋“œํ•œ ๊ณต๊ฐœ ํ‚ค์˜ ํŒŒ์ผ ์ด๋ฆ„์€ ๋‹ค์Œ ํ˜•์‹์ž…๋‹ˆ๋‹ค.

    KEY_RING-KEY_NAME-KEY_VERSION.pub
    

    ํŒŒ์ผ ์ด๋ฆ„์˜ ๊ฐ ๋ถ€๋ถ„์ด ํ•˜์ดํ”ˆ์œผ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค(์˜ˆ: ringname-keyname-version.pub).

    gcloud

    ๋ช…๋ น์ค„์—์„œ Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์ตœ์‹  ๋ฒ„์ „์˜ Google Cloud CLI๋กœ ์„ค์น˜ ๋˜๋Š” ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”.

    gcloud kms keys versions get-public-key KEY_VERSION \
        --key KEY_NAME \
        --keyring KEY_RING \
        --location LOCATION \
        --public-key-format PUBLIC_KEY_FORMAT \
        --output-file OUTPUT_FILE_PATH
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • KEY_VERSION: ํ‚ค ๋ฒ„์ „ ๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค.
    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • PUBLIC_KEY_FORMAT: ๊ณต๊ฐœ ํ‚ค๋ฅผ ๋‚ด๋ณด๋‚ผ ํ˜•์‹์ž…๋‹ˆ๋‹ค. PQC ์•Œ๊ณ ๋ฆฌ์ฆ˜(๋ฏธ๋ฆฌ๋ณด๊ธฐ)์˜ ๊ฒฝ์šฐ nist-pqc๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ชจ๋“  ํ‚ค์˜ ๊ฒฝ์šฐ pem์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • OUTPUT_FILE_PATH: ๊ณต๊ฐœ ํ‚ค ํŒŒ์ผ์„ ์ €์žฅํ•  ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค(์˜ˆ: public-key.pub).

    ๋ชจ๋“  ํ”Œ๋ž˜๊ทธ ๋ฐ ๊ฐ€๋Šฅํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด --help ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

    C#

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € C# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS C# SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    
    using Google.Cloud.Kms.V1;
    
    public class GetPublicKeySample
    {
        public PublicKey GetPublicKey(string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring", string keyId = "my-key", string keyVersionId = "123")
        {
            // Create the client.
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
    
            // Build the key version name.
            CryptoKeyVersionName keyVersionName = new CryptoKeyVersionName(projectId, locationId, keyRingId, keyId, keyVersionId);
    
            // Call the API.
            PublicKey result = client.GetPublicKey(keyVersionName);
    
            // Return the ciphertext.
            return result;
        }
    }

    Go

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Go ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Go SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import (
    	"context"
    	"crypto/x509"
    	"encoding/pem"
    	"fmt"
    	"hash/crc32"
    	"io"
    
    	kms "cloud.google.com/go/kms/apiv1"
    	"cloud.google.com/go/kms/apiv1/kmspb"
    )
    
    // getPublicKey retrieves the public key from an asymmetric key pair on
    // Cloud KMS.
    func getPublicKey(w io.Writer, name string) error {
    	// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key/cryptoKeyVersions/123"
    
    	// 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.GetPublicKeyRequest{
    		Name: name,
    	}
    
    	// Call the API.
    	result, err := client.GetPublicKey(ctx, req)
    	if err != nil {
    		return fmt.Errorf("failed to get public key: %w", err)
    	}
    
    	// The 'Pem' field is the raw string representation of the public key.
    	// Convert 'Pem' into bytes for further processing.
    	key := []byte(result.Pem)
    
    	// Optional, but recommended: perform integrity verification on result.
    	// For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
    	// https://cloud.google.com/kms/docs/data-integrity-guidelines
    	crc32c := func(data []byte) uint32 {
    		t := crc32.MakeTable(crc32.Castagnoli)
    		return crc32.Checksum(data, t)
    	}
    	if int64(crc32c(key)) != result.PemCrc32C.Value {
    		return fmt.Errorf("getPublicKey: response corrupted in-transit")
    	}
    
    	// Optional - parse the public key. This transforms the string key into a Go
    	// PublicKey.
    	block, _ := pem.Decode(key)
    	publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
    	if err != nil {
    		return fmt.Errorf("failed to parse public key: %w", err)
    	}
    	fmt.Fprintf(w, "Retrieved public key: %v\n", publicKey)
    	return nil
    }
    

    Java

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € ์ž๋ฐ” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS ์ž๋ฐ” SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import com.google.cloud.kms.v1.CryptoKeyVersionName;
    import com.google.cloud.kms.v1.KeyManagementServiceClient;
    import com.google.cloud.kms.v1.PublicKey;
    import java.io.IOException;
    import java.security.GeneralSecurityException;
    
    public class GetPublicKey {
    
      public void getPublicKey() throws IOException, GeneralSecurityException {
        // TODO(developer): Replace these variables before running the sample.
        String projectId = "your-project-id";
        String locationId = "us-east1";
        String keyRingId = "my-key-ring";
        String keyId = "my-key";
        String keyVersionId = "123";
        getPublicKey(projectId, locationId, keyRingId, keyId, keyVersionId);
      }
    
      // Get the public key associated with an asymmetric key.
      public void getPublicKey(
          String projectId, String locationId, String keyRingId, String keyId, String keyVersionId)
          throws IOException, GeneralSecurityException {
        // 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 key version name from the project, location, key ring, key,
          // and key version.
          CryptoKeyVersionName keyVersionName =
              CryptoKeyVersionName.of(projectId, locationId, keyRingId, keyId, keyVersionId);
    
          // Get the public key.
          PublicKey publicKey = client.getPublicKey(keyVersionName);
          System.out.printf("Public key: %s%n", publicKey.getPem());
        }
      }
    }

    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 keyId = 'my-key';
    
    // Imports the Cloud KMS library
    const {KeyManagementServiceClient} = require('@google-cloud/kms');
    
    // Instantiates a client
    const client = new KeyManagementServiceClient();
    
    // Build the key version name
    const versionName = client.cryptoKeyVersionPath(
      projectId,
      locationId,
      keyRingId,
      keyId,
      versionId
    );
    
    async function getPublicKey() {
      const [publicKey] = await client.getPublicKey({
        name: versionName,
      });
    
      // Optional, but recommended: perform integrity verification on publicKey.
      // For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
      // https://cloud.google.com/kms/docs/data-integrity-guidelines
      const crc32c = require('fast-crc32c');
      if (publicKey.name !== versionName) {
        throw new Error('GetPublicKey: request corrupted in-transit');
      }
      if (crc32c.calculate(publicKey.pem) !== Number(publicKey.pemCrc32c.value)) {
        throw new Error('GetPublicKey: response corrupted in-transit');
      }
    
      console.log(`Public key pem: ${publicKey.pem}`);
    
      return publicKey;
    }
    
    return getPublicKey();

    PHP

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Google Cloud์—์„œ PHP ์‚ฌ์šฉ์— ๊ด€ํ•ด ์•Œ์•„๋ณด๊ณ  Cloud KMS PHP SDK๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”.

    use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
    use Google\Cloud\Kms\V1\GetPublicKeyRequest;
    
    function get_public_key(
        string $projectId = 'my-project',
        string $locationId = 'us-east1',
        string $keyRingId = 'my-key-ring',
        string $keyId = 'my-key',
        string $versionId = '123'
    ) {
        // Create the Cloud KMS client.
        $client = new KeyManagementServiceClient();
    
        // Build the key version name.
        $keyVersionName = $client->cryptoKeyVersionName($projectId, $locationId, $keyRingId, $keyId, $versionId);
    
        // Call the API.
        $getPublicKeyRequest = (new GetPublicKeyRequest())
            ->setName($keyVersionName);
        $publicKey = $client->getPublicKey($getPublicKeyRequest);
        printf('Public key: %s' . PHP_EOL, $publicKey->getPem());
    
        return $publicKey;
    }

    Python

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Python SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    from google.cloud import kms
    
    
    def get_public_key(
        project_id: str, location_id: str, key_ring_id: str, key_id: str, version_id: str
    ) -> kms.PublicKey:
        """
        Get the public key for an asymmetric key.
    
        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').
            key_id (string): ID of the key to use (e.g. 'my-key').
            version_id (string): ID of the key to use (e.g. '1').
    
        Returns:
            PublicKey: Cloud KMS public key response.
    
        """
    
        # Create the client.
        client = kms.KeyManagementServiceClient()
    
        # Build the key version name.
        key_version_name = client.crypto_key_version_path(
            project_id, location_id, key_ring_id, key_id, version_id
        )
    
        # Call the API.
        public_key = client.get_public_key(request={"name": key_version_name})
    
        # Optional, but recommended: perform integrity verification on public_key.
        # For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
        # https://cloud.google.com/kms/docs/data-integrity-guidelines
        if not public_key.name == key_version_name:
            raise Exception("The request sent to the server was corrupted in-transit.")
        # See crc32c() function defined below.
        if not public_key.pem_crc32c == crc32c(public_key.pem.encode("utf-8")):
            raise Exception(
                "The response received from the server was corrupted in-transit."
            )
        # End integrity verification
    
        print(f"Public key: {public_key.pem}")
        return public_key
    
    
    def crc32c(data: bytes) -> int:
        """
        Calculates the CRC32C checksum of the provided data.
        Args:
            data: the bytes over which the checksum should be calculated.
        Returns:
            An int representing the CRC32C checksum of the provided bytes.
        """
        import crcmod  # type: ignore
    
        crc32c_fun = crcmod.predefined.mkPredefinedCrcFun("crc-32c")
        return crc32c_fun(data)
    
    

    Ruby

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Ruby ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Ruby SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    # TODO(developer): uncomment these values before running the sample.
    # project_id  = "my-project"
    # location_id = "us-east1"
    # key_ring_id = "my-key-ring"
    # key_id      = "my-key"
    # version_id  = "123"
    
    # Require the library.
    require "google/cloud/kms"
    
    # Create the client.
    client = Google::Cloud::Kms.key_management_service
    
    # Build the key version name.
    key_version_name = client.crypto_key_version_path project:            project_id,
                                                      location:           location_id,
                                                      key_ring:           key_ring_id,
                                                      crypto_key:         key_id,
                                                      crypto_key_version: version_id
    
    # Call the API.
    public_key = client.get_public_key name: key_version_name
    puts "Public key: #{public_key.pem}"

    API

    ์ด ์˜ˆ์‹œ์—์„œ๋Š” curl์„ HTTP ํด๋ผ์ด์–ธํŠธ๋กœ ์‚ฌ์šฉํ•˜์—ฌ API ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ์ œ์–ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud KMS API ์•ก์„ธ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    CryptoKeyVersions.getPublicKey ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ณต๊ฐœ ํ‚ค๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/KEY_VERSION/publicKey?public_key_format=PUBLIC_KEY_FORMAT" \
        --request "GET" \
        --header "authorization: Bearer TOKEN"
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: ํ‚ค๋ง์ด ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ID์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_VERSION: ํ‚ค ๋ฒ„์ „ ๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค.
    • PUBLIC_KEY_FORMAT: ๊ณต๊ฐœ ํ‚ค๋ฅผ ๋‚ด๋ณด๋‚ผ ํ˜•์‹์ž…๋‹ˆ๋‹ค. PQC ์•Œ๊ณ ๋ฆฌ์ฆ˜(๋ฏธ๋ฆฌ๋ณด๊ธฐ)์˜ ๊ฒฝ์šฐ NIST_PQC๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ชจ๋“  ํ‚ค์˜ ๊ฒฝ์šฐ PEM์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    PQC๊ฐ€ ์•„๋‹Œ ํ‚ค์˜ ๊ณต๊ฐœ ํ‚ค ํ˜•์‹์„ ์ƒ๋žตํ•˜๋ฉด ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

    {
      "pem": "-----BEGIN PUBLIC KEY-----\nQ29uZ3JhdHVsYXRpb25zLCB5b3UndmUgZGlzY292ZX
              JlZCB0aGF0IHRoaXMgaXNuJ3QgYWN0dWFsbHkgYSBwdWJsaWMga2V5ISBIYXZlIGEgbmlj
              ZSBkYXkgOik=\n-----END PUBLIC KEY-----\n",
      "algorithm": "ALGORITHM",
      "pemCrc32c": "2561089887",
      "name": "projects/PROJECT_ID/locations/LOCATION/keyRings/
               KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/
               KEY_VERSION",
      "protectionLevel": "PROTECTION_LEVEL"
    }

    ๊ณต๊ฐœ ํ‚ค ํ˜•์‹์ด NIST_PQC์ธ PQC ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ฒฝ์šฐ ์ถœ๋ ฅ์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

    {
      "publicKeyFormat": "NIST_PQC",
      "publicKey": {
        "crc32cChecksum": "1985843562",
        "data": "kdcOIrFCC5kN8S4i0+R+AoSc9gYIJ9jEQ6zG235ZmCQ="
      }
      "algorithm": "ALGORITHM",
      "name": "projects/PROJECT_ID/locations/LOCATION/keyRings/
               KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/
               KEY_VERSION",
      "protectionLevel": "PROTECTION_LEVEL"
    }

    ๊ณต๊ฐœ ํ‚ค๋ฅผ JWK ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜

    Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด PEM ํ˜•์‹์œผ๋กœ ๊ณต๊ฐœ ํ‚ค๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” JSON ์›น ํ‚ค(JWK)์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ํ‚ค ํ˜•์‹์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. JWK ํ˜•์‹์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ RFC 7517์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ๊ณต๊ฐœ ํ‚ค๋ฅผ JWK ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

    Go

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Go ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Go SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import (
    	"context"
    	"crypto/x509"
    	"encoding/json"
    	"encoding/pem"
    	"fmt"
    	"hash/crc32"
    	"io"
    
    	kms "cloud.google.com/go/kms/apiv1"
    	"cloud.google.com/go/kms/apiv1/kmspb"
    	"github.com/lestrrat-go/jwx/v2/jwk"
    )
    
    // getPublicKeyJwk retrieves the public key from an asymmetric key pair on Cloud KMS.
    func getPublicKeyJwk(w io.Writer, cryptoKeyVersionName string) error {
    	// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key/cryptoKeyVersions/123"
    
    	// 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.GetPublicKeyRequest{
    		Name: cryptoKeyVersionName,
    	}
    
    	// Call the API to get the public key.
    	result, err := client.GetPublicKey(ctx, req)
    	if err != nil {
    		return fmt.Errorf("failed to get public key: %w", err)
    	}
    
    	// The 'Pem' field is the raw string representation of the public key.
    	// Convert 'Pem' into bytes for further processing.
    	key := []byte(result.Pem)
    
    	// Optional, but recommended: perform integrity verification on result.
    	// For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
    	// https://cloud.google.com/kms/docs/data-integrity-guidelines
    	crc32c := func(data []byte) uint32 {
    		t := crc32.MakeTable(crc32.Castagnoli)
    		return crc32.Checksum(data, t)
    	}
    	if int64(crc32c(key)) != result.PemCrc32C.Value {
    		return fmt.Errorf("getPublicKey: response corrupted in-transit")
    	}
    
    	// Optional - parse the public key.
    	// This transforms the string key into a Go PublicKey.
    	block, _ := pem.Decode(key)
    	_, err = x509.ParsePKIXPublicKey(block.Bytes)
    	if err != nil {
    		return fmt.Errorf("failed to parse public key: %w", err)
    	}
    
    	// If all above checks pass, convert it into JWK format.
    	jwkKey, err := jwk.ParseKey(key, jwk.WithPEM(true))
    	if err != nil {
    		return fmt.Errorf("Failed to parse the PEM public key: %w", err)
    	}
    
    	fmt.Fprintf(w, "The public key in JWK format: ")
    	json.NewEncoder(w).Encode(jwkKey)
    	return nil
    }
    

    Java

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € ์ž๋ฐ” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS ์ž๋ฐ” SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import com.google.cloud.kms.v1.CryptoKeyVersionName;
    import com.google.cloud.kms.v1.KeyManagementServiceClient;
    import com.google.cloud.kms.v1.PublicKey;
    // NOTE: The library nimbusds is NOT endorsed for anything beyond conversion to JWK.
    import com.nimbusds.jose.JOSEException;
    import com.nimbusds.jose.jwk.JWK;
    import java.io.IOException;
    import java.security.GeneralSecurityException;
    
    public class ConvertPublicKeyToJwk {
    
      public void convertPublicKey() throws IOException, GeneralSecurityException, JOSEException {
        // TODO(developer): Replace these variables before running the sample.
        String projectId = "your-project-id";
        String locationId = "us-east1";
        String keyRingId = "my-key-ring";
        String keyId = "my-key";
        String keyVersionId = "123";
        convertPublicKey(projectId, locationId, keyRingId, keyId, keyVersionId);
      }
    
      // (Get and) Convert the public key associated with an asymmetric key.
      public void convertPublicKey(
          String projectId, String locationId, String keyRingId, String keyId, String keyVersionId)
          throws IOException, GeneralSecurityException, JOSEException {
        // 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 key version name from the project, location, key ring, key,
          // and key version.
          CryptoKeyVersionName keyVersionName =
              CryptoKeyVersionName.of(projectId, locationId, keyRingId, keyId, keyVersionId);
    
          // Get the public key and convert it to JWK format.
          PublicKey publicKey = client.getPublicKey(keyVersionName);
          JWK jwk = JWK.parseFromPEMEncodedObjects(publicKey.getPem());
          System.out.println(jwk.toJSONString());
        }
      }
    }

    Python

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Python SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    from google.cloud import kms
    from jwcrypto import jwk
    
    
    def get_public_key_jwk(
        project_id: str, location_id: str, key_ring_id: str, key_id: str, version_id: str
    ) -> kms.PublicKey:
        """
        Get the public key of an asymmetric key in JWK format.
    
        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').
            key_id (string): ID of the key to use (e.g. 'my-key').
            version_id (string): ID of the key to use (e.g. '1').
    
        Returns:
            PublicKey: Cloud KMS public key response.
    
        """
    
        # Create the client.
        client = kms.KeyManagementServiceClient()
    
        # Build the key version name.
        key_version_name = client.crypto_key_version_path(
            project_id, location_id, key_ring_id, key_id, version_id
        )
    
        # Call the API.
        public_key = client.get_public_key(request={"name": key_version_name})
    
        # Optional, but recommended: perform integrity verification on public_key.
        # For more details on ensuring E2E in-transit integrity to and from Cloud KMS visit:
        # https://cloud.google.com/kms/docs/data-integrity-guidelines
        if not public_key.name == key_version_name:
            raise Exception("The request sent to the server was corrupted in-transit.")
        # See crc32c() function defined below.
        if not public_key.pem_crc32c == crc32c(public_key.pem.encode("utf-8")):
            raise Exception(
                "The response received from the server was corrupted in-transit."
            )
        # End integrity verification
    
        # Convert to JWK format.
        jwk_key = jwk.JWK.from_pem(public_key.pem.encode())
        return jwk_key.export(private_key=False)
    
    
    def crc32c(data: bytes) -> int:
        """
        Calculates the CRC32C checksum of the provided data.
        Args:
            data: the bytes over which the checksum should be calculated.
        Returns:
            An int representing the CRC32C checksum of the provided bytes.
        """
        import crcmod  # type: ignore
    
        crc32c_fun = crcmod.predefined.mkPredefinedCrcFun("crc-32c")
        return crc32c_fun(data)
    
    

    ๋น„๋Œ€์นญ ํ‚ค์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ์ œ์–ด

    ์„œ๋ช…์ž ๋˜๋Š” ๊ฒ€์ฆ์ž์—๊ฒŒ๋Š” ๋น„๋Œ€์นญ ํ‚ค์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ๊ถŒํ•œ ๋˜๋Š” ์—ญํ• ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

    • ์„œ๋ช…์„ ์ˆ˜ํ–‰ํ•  ์‚ฌ์šฉ์ž ๋˜๋Š” ์„œ๋น„์Šค์˜ ๊ฒฝ์šฐ ๋น„๋Œ€์นญ ํ‚ค์— ๋Œ€ํ•œ cloudkms.cryptoKeyVersions.useToSign ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

    • ๊ณต๊ฐœ ํ‚ค๋ฅผ ๊ฒ€์ƒ‰ํ•  ์‚ฌ์šฉ์ž ๋˜๋Š” ์„œ๋น„์Šค์— ๋น„๋Œ€์นญ ํ‚ค์— ๋Œ€ํ•œ cloudkms.cryptoKeyVersions.viewPublicKey๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ฐœ ํ‚ค๋Š” ์„œ๋ช… ๊ฒ€์ฆ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

    ๊ถŒํ•œ ๋ฐ ์—ญํ• ์—์„œ Cloud KMS ์ถœ์‹œ ๋ฒ„์ „์˜ ๊ถŒํ•œ ๋ฐ ์—ญํ• ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์„ธ์š”.

    MAC ์„œ๋ช… ํ‚ค ๋งŒ๋“ค๊ธฐ

    ์ฝ˜์†”

    1. Google Cloud ์ฝ˜์†”์—์„œ ํ‚ค ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

      Key Management Service๋กœ ์ด๋™

    2. ํ‚ค๋ฅผ ๋งŒ๋“ค ํ‚ค๋ง์˜ ์ด๋ฆ„์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    3. ํ‚ค ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    4. ํ‚ค ์ด๋ฆ„์— ํ‚ค์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    5. ๋ณดํ˜ธ ์ˆ˜์ค€์—์„œ ์†Œํ”„ํŠธ์›จ์–ด ๋˜๋Š” HSM์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    6. ํ‚ค ์ž๋ฃŒ์—์„œ ์ƒ์„ฑ๋œ ํ‚ค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    7. ์šฉ๋„์—์„œ MAC ์„œ๋ช…/ํ™•์ธ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    8. ์„ ํƒ์‚ฌํ•ญ: ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ HMAC ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    9. ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

    gcloud

    ๋ช…๋ น์ค„์—์„œ Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์ตœ์‹  ๋ฒ„์ „์˜ Google Cloud CLI๋กœ ์„ค์น˜ ๋˜๋Š” ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”.

    gcloud kms keys create KEY_NAME \
        --keyring KEY_RING \
        --location LOCATION \
        --purpose "mac" \
        --default-algorithm "ALGORITHM" \
        --protection-level "PROTECTION_LEVEL"
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • ALGORITHM: HMAC ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค(์˜ˆ: hmac-sha256). ์ง€์›๋˜๋Š” ๋ชจ๋“  HMAC ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ณด๋ ค๋ฉด HMAC ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.
    • PROTECTION_LEVEL: ํ‚ค์˜ ๋ณดํ˜ธ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค(์˜ˆ: hsm). software ํ‚ค์˜ --protection-level ํ”Œ๋ž˜๊ทธ๋Š” ์ƒ๋žตํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

    ๋ชจ๋“  ํ”Œ๋ž˜๊ทธ ๋ฐ ๊ฐ€๋Šฅํ•œ ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ณด๋ ค๋ฉด --help ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

    C#

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € C# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS C# SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    
    using Google.Cloud.Kms.V1;
    using Google.Protobuf.WellKnownTypes;
    
    public class CreateKeyMacSample
    {
        public CryptoKey CreateKeyMac(
          string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring",
          string id = "my-mac-key")
        {
            // Create the client.
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
    
            // Build the parent key ring name.
            KeyRingName keyRingName = new KeyRingName(projectId, locationId, keyRingId);
    
            // Build the key.
            CryptoKey key = new CryptoKey
            {
                Purpose = CryptoKey.Types.CryptoKeyPurpose.Mac,
                VersionTemplate = new CryptoKeyVersionTemplate
                {
                    Algorithm = CryptoKeyVersion.Types.CryptoKeyVersionAlgorithm.HmacSha256,
                },
    
                // Optional: customize how long key versions should be kept before destroying.
                DestroyScheduledDuration = new Duration
                {
                    Seconds = 24 * 60 * 60,
                }
            };
    
            // Call the API.
            CryptoKey result = client.CreateCryptoKey(keyRingName, id, key);
    
            // Return the result.
            return result;
        }
    }

    Go

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Go ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Go SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    import (
    	"context"
    	"fmt"
    	"io"
    	"time"
    
    	kms "cloud.google.com/go/kms/apiv1"
    	"cloud.google.com/go/kms/apiv1/kmspb"
    	"google.golang.org/protobuf/types/known/durationpb"
    )
    
    // createKeyMac creates a new key for use with MacSign.
    func createKeyMac(w io.Writer, parent, id string) error {
    	// parent := "projects/my-project/locations/us-east1/keyRings/my-key-ring"
    	// id := "my-mac-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_MAC,
    			VersionTemplate: &kmspb.CryptoKeyVersionTemplate{
    				Algorithm: kmspb.CryptoKeyVersion_HMAC_SHA256,
    			},
    
    			// Optional: customize how long key versions should be kept before destroying.
    			DestroyScheduledDuration: durationpb.New(24 * time.Hour),
    		},
    	}
    
    	// 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

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € ์ž๋ฐ” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS ์ž๋ฐ” SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    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 java.io.IOException;
    
    public class CreateKeyMac {
    
      public void createKeyMac() 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-mac-key";
        createKeyMac(projectId, locationId, keyRingId, id);
      }
    
      // Create a new key for use with MacSign.
      public void createKeyMac(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);
    
          // Build the mac key to create.
          CryptoKey key =
              CryptoKey.newBuilder()
                  .setPurpose(CryptoKeyPurpose.MAC)
                  .setVersionTemplate(
                      CryptoKeyVersionTemplate.newBuilder()
                          .setAlgorithm(CryptoKeyVersionAlgorithm.HMAC_SHA256))
                  .build();
    
          // Create the key.
          CryptoKey createdKey = client.createCryptoKey(keyRingName, id, key);
          System.out.printf("Created mac 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-mac-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 createKeyMac() {
      const [key] = await client.createCryptoKey({
        parent: keyRingName,
        cryptoKeyId: id,
        cryptoKey: {
          purpose: 'MAC',
          versionTemplate: {
            algorithm: 'HMAC_SHA256',
          },
    
          // Optional: customize how long key versions should be kept before
          // destroying.
          destroyScheduledDuration: {seconds: 60 * 60 * 24},
        },
      });
    
      console.log(`Created mac key: ${key.name}`);
      return key;
    }
    
    return createKeyMac();

    PHP

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Google Cloud์—์„œ PHP ์‚ฌ์šฉ์— ๊ด€ํ•ด ์•Œ์•„๋ณด๊ณ  Cloud KMS PHP SDK๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”.

    use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
    use Google\Cloud\Kms\V1\CreateCryptoKeyRequest;
    use Google\Cloud\Kms\V1\CryptoKey;
    use Google\Cloud\Kms\V1\CryptoKey\CryptoKeyPurpose;
    use Google\Cloud\Kms\V1\CryptoKeyVersion\CryptoKeyVersionAlgorithm;
    use Google\Cloud\Kms\V1\CryptoKeyVersionTemplate;
    use Google\Protobuf\Duration;
    
    function create_key_mac(
        string $projectId = 'my-project',
        string $locationId = 'us-east1',
        string $keyRingId = 'my-key-ring',
        string $id = 'my-mac-key'
    ): CryptoKey {
        // Create the Cloud KMS client.
        $client = new KeyManagementServiceClient();
    
        // Build the parent key ring name.
        $keyRingName = $client->keyRingName($projectId, $locationId, $keyRingId);
    
        // Build the key.
        $key = (new CryptoKey())
            ->setPurpose(CryptoKeyPurpose::MAC)
            ->setVersionTemplate((new CryptoKeyVersionTemplate())
                ->setAlgorithm(CryptoKeyVersionAlgorithm::HMAC_SHA256)
            )
    
            // Optional: customize how long key versions should be kept before destroying.
            ->setDestroyScheduledDuration((new Duration())
                ->setSeconds(24 * 60 * 60)
            );
    
        // Call the API.
        $createCryptoKeyRequest = (new CreateCryptoKeyRequest())
            ->setParent($keyRingName)
            ->setCryptoKeyId($id)
            ->setCryptoKey($key);
        $createdKey = $client->createCryptoKey($createCryptoKeyRequest);
        printf('Created mac key: %s' . PHP_EOL, $createdKey->getName());
    
        return $createdKey;
    }

    Python

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Python ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Python SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    
    import datetime
    
    from google.cloud import kms
    from google.protobuf import duration_pb2  # type: ignore
    
    
    def create_key_mac(
        project_id: str, location_id: str, key_ring_id: str, key_id: str
    ) -> kms.CryptoKey:
        """
        Creates a new key in Cloud KMS for HMAC operations.
    
        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').
            key_id (string): ID of the key to create (e.g. 'my-mac-key').
    
        Returns:
            CryptoKey: Cloud KMS key.
    
        """
    
        # Create the client.
        client = kms.KeyManagementServiceClient()
    
        # Build the parent key ring name.
        key_ring_name = client.key_ring_path(project_id, location_id, key_ring_id)
    
        # Build the key.
        purpose = kms.CryptoKey.CryptoKeyPurpose.MAC
        algorithm = kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.HMAC_SHA256
        key = {
            "purpose": purpose,
            "version_template": {
                "algorithm": algorithm,
            },
            # Optional: customize how long key versions should be kept before
            # destroying.
            "destroy_scheduled_duration": duration_pb2.Duration().FromTimedelta(
                datetime.timedelta(days=1)
            ),
        }
    
        # Call the API.
        created_key = client.create_crypto_key(
            request={"parent": key_ring_name, "crypto_key_id": key_id, "crypto_key": key}
        )
        print(f"Created mac key: {created_key.name}")
        return created_key
    
    

    Ruby

    ์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋จผ์ € Ruby ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ณ  Cloud KMS Ruby SDK๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

    # TODO(developer): uncomment these values before running the sample.
    # project_id  = "my-project"
    # location_id = "us-east1"
    # key_ring_id = "my-key-ring"
    # id          = "my-mac-key"
    
    # Require the library.
    require "google/cloud/kms"
    
    # Create the client.
    client = Google::Cloud::Kms.key_management_service
    
    # Build the parent key ring name.
    key_ring_name = client.key_ring_path project: project_id, location: location_id, key_ring: key_ring_id
    
    # Build the key.
    key = {
      purpose:          :MAC,
      version_template: {
        algorithm: :HMAC_SHA256
      }
    }
    
    # Call the API.
    created_key = client.create_crypto_key parent: key_ring_name, crypto_key_id: id, crypto_key: key
    puts "Created mac key: #{created_key.name}"

    API

    ์ด ์˜ˆ์‹œ์—์„œ๋Š” curl์„ HTTP ํด๋ผ์ด์–ธํŠธ๋กœ ์‚ฌ์šฉํ•˜์—ฌ API ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์•ก์„ธ์Šค ์ œ์–ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud KMS API ์•ก์„ธ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

    ํ‚ค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด CryptoKey.create ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys?crypto_key_id=KEY_NAME" \
        --request "POST" \
        --header "authorization: Bearer TOKEN" \
        --header "content-type: application/json" \
        --data '{"purpose": "MAC", "versionTemplate": { "protectionLevel": "PROTECTION_LEVEL", "algorithm": "ALGORITHM" }}'
    

    ๋‹ค์Œ์„ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

    • PROJECT_ID: ํ‚ค๋ง์ด ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ID์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • KEY_NAME: ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • PROTECTION_LEVEL: ํ‚ค์˜ ๋ณดํ˜ธ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค(์˜ˆ: SOFTWARE ๋˜๋Š” HSM).
    • ALGORITHM: HMAC ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค(์˜ˆ: HMAC_SHA256). ์ง€์›๋˜๋Š” ๋ชจ๋“  HMAC ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ณด๋ ค๋ฉด HMAC ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

    ๋‹ค์Œ ๋‹จ๊ณ„