Cloud HSM

์ด ์ฃผ์ œ์—์„œ๋Š” Cloud HSM์˜ ๊ฐœ์š”๋ฅผ ์‚ดํŽด๋ณด๊ณ  Cloud Key Management Service์—์„œ HSM์œผ๋กœ ๋ณดํ˜ธ๋˜๋Š” ์•”ํ˜ธํ™” ํ‚ค๋ฅผ ๋งŒ๋“ค๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Cloud HSM์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Cloud HSM์€ ํด๋ผ์šฐ๋“œ์— ํ˜ธ์ŠคํŒ…๋˜๋Š” ํ•˜๋“œ์›จ์–ด ๋ณด์•ˆ ๋ชจ๋“ˆ(HSM) ์„œ๋น„์Šค๋กœ, ์ด ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด FIPS 140-2 Level 3 ์ธ์ฆ HSM ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์•”ํ˜ธํ™” ํ‚ค๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๊ณ  ์•”ํ˜ธํ™” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Google์ด HSM ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ ๊ฐœ๋ฐœ์ž๋Š” ํด๋Ÿฌ์Šคํ„ฐ๋ง, ํ™•์žฅ ๋˜๋Š” ํŒจ์น˜ ์ ์šฉ์— ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. Cloud HSM์€ ํ”„๋ŸฐํŠธ์—”๋“œ๋กœ Cloud KMS๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๊ฐœ๋ฐœ์ž๋Š” Cloud KMS๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  ํŽธ์˜์„ฑ ๋ฐ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

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

Cloud HSM์„ ์ง€์›ํ•˜๋Š” Google Cloud ์œ„์น˜์— ํ‚ค๋ง์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ฝ˜์†”

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

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

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

  3. ํ‚ค๋ง ์ด๋ฆ„์— ํ‚ค๋ง ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  4. ํ‚ค๋ง ์œ„์น˜์—์„œ "us-east1"๊ณผ ๊ฐ™์€ ์œ„์น˜๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

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

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  2. ํ™˜๊ฒฝ์—์„œ gcloud kms keyrings create ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    gcloud kms keyrings create KEY_RING \
        --location LOCATION
    

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

    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.

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

  3. C#

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

    
    using Google.Api.Gax.ResourceNames;
    using Google.Cloud.Kms.V1;
    
    public class CreateKeyRingSample
    {
        public KeyRing CreateKeyRing(
          string projectId = "my-project", string locationId = "us-east1",
          string id = "my-key-ring")
        {
            // Create the client.
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
    
            // Build the parent location name.
            LocationName locationName = new LocationName(projectId, locationId);
    
            // Build the key ring.
            KeyRing keyRing = new KeyRing { };
    
            // Call the API.
            KeyRing result = client.CreateKeyRing(locationName, id, keyRing);
    
            // 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"
    )
    
    // createKeyRing creates a new ring to store keys on KMS.
    func createKeyRing(w io.Writer, parent, id string) error {
    	// parent := "projects/PROJECT_ID/locations/global"
    	// id := "my-key-ring"
    
    	// 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.CreateKeyRingRequest{
    		Parent:    parent,
    		KeyRingId: id,
    	}
    
    	// Call the API.
    	result, err := client.CreateKeyRing(ctx, req)
    	if err != nil {
    		return fmt.Errorf("failed to create key ring: %w", err)
    	}
    	fmt.Fprintf(w, "Created key ring: %s\n", result.Name)
    	return nil
    }
    

    Java

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

    import com.google.cloud.kms.v1.KeyManagementServiceClient;
    import com.google.cloud.kms.v1.KeyRing;
    import com.google.cloud.kms.v1.LocationName;
    import java.io.IOException;
    
    public class CreateKeyRing {
    
      public void createKeyRing() throws IOException {
        // TODO(developer): Replace these variables before running the sample.
        String projectId = "your-project-id";
        String locationId = "us-east1";
        String id = "my-asymmetric-signing-key";
        createKeyRing(projectId, locationId, id);
      }
    
      // Create a new key ring.
      public void createKeyRing(String projectId, String locationId, 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 and location.
          LocationName locationName = LocationName.of(projectId, locationId);
    
          // Build the key ring to create.
          KeyRing keyRing = KeyRing.newBuilder().build();
    
          // Create the key ring.
          KeyRing createdKeyRing = client.createKeyRing(locationName, id, keyRing);
          System.out.printf("Created key ring %s%n", createdKeyRing.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 id = 'my-key-ring';
    
    // Imports the Cloud KMS library
    const {KeyManagementServiceClient} = require('@google-cloud/kms');
    
    // Instantiates a client
    const client = new KeyManagementServiceClient();
    
    // Build the parent location name
    const locationName = client.locationPath(projectId, locationId);
    
    async function createKeyRing() {
      const [keyRing] = await client.createKeyRing({
        parent: locationName,
        keyRingId: id,
      });
    
      console.log(`Created key ring: ${keyRing.name}`);
      return keyRing;
    }
    
    return createKeyRing();

    PHP

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

    use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
    use Google\Cloud\Kms\V1\CreateKeyRingRequest;
    use Google\Cloud\Kms\V1\KeyRing;
    
    function create_key_ring(
        string $projectId = 'my-project',
        string $locationId = 'us-east1',
        string $id = 'my-key-ring'
    ): KeyRing {
        // Create the Cloud KMS client.
        $client = new KeyManagementServiceClient();
    
        // Build the parent location name.
        $locationName = $client->locationName($projectId, $locationId);
    
        // Build the key ring.
        $keyRing = new KeyRing();
    
        // Call the API.
        $createKeyRingRequest = (new CreateKeyRingRequest())
            ->setParent($locationName)
            ->setKeyRingId($id)
            ->setKeyRing($keyRing);
        $createdKeyRing = $client->createKeyRing($createKeyRingRequest);
        printf('Created key ring: %s' . PHP_EOL, $createdKeyRing->getName());
    
        return $createdKeyRing;
    }

    Python

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

    from google.cloud import kms
    
    
    def create_key_ring(
        project_id: str, location_id: str, key_ring_id: str
    ) -> kms.CryptoKey:
        """
        Creates a new key ring 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 key ring to create (e.g. 'my-key-ring').
    
        Returns:
            KeyRing: Cloud KMS key ring.
    
        """
    
        # Create the client.
        client = kms.KeyManagementServiceClient()
    
        # Build the parent location name.
        location_name = f"projects/{project_id}/locations/{location_id}"
    
        # Build the key ring.
        key_ring = {}
    
        # Call the API.
        created_key_ring = client.create_key_ring(
            request={
                "parent": location_name,
                "key_ring_id": key_ring_id,
                "key_ring": key_ring,
            }
        )
        print(f"Created key ring: {created_key_ring.name}")
        return created_key_ring
    
    

    Ruby

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

    # TODO(developer): uncomment these values before running the sample.
    # project_id  = "my-project"
    # location_id = "us-east1"
    # id = "my-key-ring"
    
    # Require the library.
    require "google/cloud/kms"
    
    # Create the client.
    client = Google::Cloud::Kms.key_management_service
    
    # Build the parent location name.
    location_name = client.location_path project: project_id, location: location_id
    
    # Build the key ring.
    key_ring = {}
    
    # Call the API.
    created_key_ring = client.create_key_ring parent: location_name, key_ring_id: id, key_ring: key_ring
    puts "Created key ring: #{created_key_ring.name}"

    API

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

    curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings?key_ring_id=KEY_RING" \
        --request "POST" \
        --header "authorization: Bearer TOKEN"
    

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

    • PROJECT_ID: ํ‚ค๋ง์ด ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ID์ž…๋‹ˆ๋‹ค.
    • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • LOCATION: ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.

    ์ž์„ธํ•œ ๋‚ด์šฉ์€ KeyRing.create API ์ฐธ๊ณ  ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

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

์ง€์ •๋œ ํ‚ค๋ง ๋ฐ ์œ„์น˜์— Cloud HSM ํ‚ค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

์ฝ˜์†”

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

    ํ‚ค ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™

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

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

  4. ์–ด๋–ค ์œ ํ˜•์˜ ํ‚ค๋ฅผ ๋งŒ๋“œ์‹œ๊ฒ ์–ด์š”?์—์„œ ์ƒ์„ฑ๋œ ํ‚ค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  5. ํ‚ค ์ด๋ฆ„ ํ•„๋“œ์— ํ‚ค ์ด๋ฆ„์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  6. ๋ณดํ˜ธ ์ˆ˜์ค€ ๋“œ๋กญ๋‹ค์šด์„ ํด๋ฆญํ•˜๊ณ  HSM์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  7. ์šฉ๋„ ๋“œ๋กญ๋‹ค์šด์„ ํด๋ฆญํ•˜๊ณ  ๋Œ€์นญ ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™”๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

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

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

gcloud

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

gcloud kms keys create key \
    --keyring key-ring \
    --location location \
    --purpose "encryption" \
    --protection-level "hsm"

key๋ฅผ ์ƒˆ ํ‚ค ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. key-ring์„ ํ‚ค๋ฅผ ๋ฐฐ์น˜ํ•  ๊ธฐ์กด ํ‚ค๋ง์˜ ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. location์„ ํ‚ค๋ง์˜ Cloud KMS ์œ„์น˜๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

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

C#

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


using Google.Cloud.Kms.V1;
using Google.Protobuf.WellKnownTypes;

public class CreateKeyHsmSample
{
    public CryptoKey CreateKeyHsm(
      string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring",
      string id = "my-hsm-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
            {
                ProtectionLevel = ProtectionLevel.Hsm,
                Algorithm = CryptoKeyVersion.Types.CryptoKeyVersionAlgorithm.GoogleSymmetricEncryption,
            },

            // 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"
)

// createKeyHSM creates a new symmetric encrypt/decrypt key on Cloud KMS.
func createKeyHSM(w io.Writer, parent, id string) error {
	// parent := "projects/my-project/locations/us-east1/keyRings/my-key-ring"
	// id := "my-hsm-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{
				ProtectionLevel: kmspb.ProtectionLevel_HSM,
				Algorithm:       kmspb.CryptoKeyVersion_GOOGLE_SYMMETRIC_ENCRYPTION,
			},

			// 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.cloud.kms.v1.ProtectionLevel;
import com.google.protobuf.Duration;
import java.io.IOException;

public class CreateKeyHsm {

  public void createKeyHsm() 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-hsm-key";
    createKeyHsm(projectId, locationId, keyRingId, id);
  }

  // Create a new key that is stored in an HSM.
  public void createKeyHsm(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 hsm key to create.
      CryptoKey key =
          CryptoKey.newBuilder()
              .setPurpose(CryptoKeyPurpose.ENCRYPT_DECRYPT)
              .setVersionTemplate(
                  CryptoKeyVersionTemplate.newBuilder()
                      .setProtectionLevel(ProtectionLevel.HSM)
                      .setAlgorithm(CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION))

              // 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 hsm 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-hsm-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 createKeyHsm() {
  const [key] = await client.createCryptoKey({
    parent: keyRingName,
    cryptoKeyId: id,
    cryptoKey: {
      purpose: 'ENCRYPT_DECRYPT',
      versionTemplate: {
        algorithm: 'GOOGLE_SYMMETRIC_ENCRYPTION',
        protectionLevel: 'HSM',
      },

      // Optional: customize how long key versions should be kept before
      // destroying.
      destroyScheduledDuration: {seconds: 60 * 60 * 24},
    },
  });

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

return createKeyHsm();

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\Cloud\Kms\V1\ProtectionLevel;
use Google\Protobuf\Duration;

function create_key_hsm(
    string $projectId = 'my-project',
    string $locationId = 'us-east1',
    string $keyRingId = 'my-key-ring',
    string $id = 'my-hsm-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)
            ->setProtectionLevel(ProtectionLevel::HSM)
        )

        // 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 hsm 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_hsm(
    project_id: str, location_id: str, key_ring_id: str, key_id: str
) -> kms.CryptoKey:
    """
    Creates a new key in Cloud KMS backed by Cloud HSM.

    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-hsm-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
    )
    protection_level = kms.ProtectionLevel.HSM
    key = {
        "purpose": purpose,
        "version_template": {
            "algorithm": algorithm,
            "protection_level": protection_level,
        },
        # 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 hsm 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-hsm-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,
    protection_level: :HSM
  },

  # 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 hsm key: #{created_key.name}"

๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™”

์ด์ œ ํ‚ค๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…์ŠคํŠธ ๋˜๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ์ฝ˜ํ…์ธ ๋ฅผ ์•”ํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

gcloud

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

gcloud kms encrypt \
    --key KEY_NAME \
    --keyring KEY_RING \
    --location LOCATION  \
    --plaintext-file FILE_TO_ENCRYPT \
    --ciphertext-file ENCRYPTED_OUTPUT

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

  • KEY_NAME: ์•”ํ˜ธํ™”์— ์‚ฌ์šฉํ•  ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • LOCATION: ํ‚ค๋ง์ด ํฌํ•จ๋œ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
  • FILE_TO_ENCRYPT: ์•”ํ˜ธํ™”ํ•˜๋ ค๋Š” ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.
  • ENCRYPTED_OUTPUT: ์•”ํ˜ธํ™”๋œ ์ถœ๋ ฅ์„ ์ €์žฅํ•  ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.

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

C#

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


using Google.Cloud.Kms.V1;
using Google.Protobuf;
using System.Text;

public class EncryptSymmetricSample
{
    public byte[] EncryptSymmetric(
      string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring", string keyId = "my-key",
      string message = "Sample message")
    {
        // Create the client.
        KeyManagementServiceClient client = KeyManagementServiceClient.Create();

        // Build the key name.
        CryptoKeyName keyName = new CryptoKeyName(projectId, locationId, keyRingId, keyId);

        // Convert the message into bytes. Cryptographic plaintexts and
        // ciphertexts are always byte arrays.
        byte[] plaintext = Encoding.UTF8.GetBytes(message);

        // Call the API.
        EncryptResponse result = client.Encrypt(keyName, ByteString.CopyFrom(plaintext));

        // Return the ciphertext.
        return result.Ciphertext.ToByteArray();
    }
}

Go

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

import (
	"context"
	"fmt"
	"hash/crc32"
	"io"

	kms "cloud.google.com/go/kms/apiv1"
	"cloud.google.com/go/kms/apiv1/kmspb"
	"google.golang.org/protobuf/types/known/wrapperspb"
)

// encryptSymmetric encrypts the input plaintext with the specified symmetric
// Cloud KMS key.
func encryptSymmetric(w io.Writer, name string, message string) error {
	// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key"
	// message := "Sample message"

	// 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()

	// Convert the message into bytes. Cryptographic plaintexts and
	// ciphertexts are always byte arrays.
	plaintext := []byte(message)

	// Optional but recommended: Compute plaintext's CRC32C.
	crc32c := func(data []byte) uint32 {
		t := crc32.MakeTable(crc32.Castagnoli)
		return crc32.Checksum(data, t)
	}
	plaintextCRC32C := crc32c(plaintext)

	// Build the request.
	req := &kmspb.EncryptRequest{
		Name:            name,
		Plaintext:       plaintext,
		PlaintextCrc32C: wrapperspb.Int64(int64(plaintextCRC32C)),
	}

	// Call the API.
	result, err := client.Encrypt(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to encrypt: %w", err)
	}

	// 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
	if result.VerifiedPlaintextCrc32C == false {
		return fmt.Errorf("Encrypt: request corrupted in-transit")
	}
	if int64(crc32c(result.Ciphertext)) != result.CiphertextCrc32C.Value {
		return fmt.Errorf("Encrypt: response corrupted in-transit")
	}

	fmt.Fprintf(w, "Encrypted ciphertext: %s", result.Ciphertext)
	return nil
}

Java

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

import com.google.cloud.kms.v1.CryptoKeyName;
import com.google.cloud.kms.v1.EncryptResponse;
import com.google.cloud.kms.v1.KeyManagementServiceClient;
import com.google.protobuf.ByteString;
import java.io.IOException;

public class EncryptSymmetric {

  public void encryptSymmetric() 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 keyId = "my-key";
    String plaintext = "Plaintext to encrypt";
    encryptSymmetric(projectId, locationId, keyRingId, keyId, plaintext);
  }

  // Encrypt data with a given key.
  public void encryptSymmetric(
      String projectId, String locationId, String keyRingId, String keyId, String plaintext)
      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 key version name from the project, location, key ring, key,
      // and key version.
      CryptoKeyName keyVersionName = CryptoKeyName.of(projectId, locationId, keyRingId, keyId);

      // Encrypt the plaintext.
      EncryptResponse response = client.encrypt(keyVersionName, ByteString.copyFromUtf8(plaintext));
      System.out.printf("Ciphertext: %s%n", response.getCiphertext().toStringUtf8());
    }
  }
}

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';
// const plaintextBuffer = Buffer.from('...');

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

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

// Build the key name
const keyName = client.cryptoKeyPath(projectId, locationId, keyRingId, keyId);

// Optional, but recommended: compute plaintext's CRC32C.
const crc32c = require('fast-crc32c');
const plaintextCrc32c = crc32c.calculate(plaintextBuffer);

async function encryptSymmetric() {
  const [encryptResponse] = await client.encrypt({
    name: keyName,
    plaintext: plaintextBuffer,
    plaintextCrc32c: {
      value: plaintextCrc32c,
    },
  });

  const ciphertext = encryptResponse.ciphertext;

  // Optional, but recommended: perform integrity verification on encryptResponse.
  // 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 (!encryptResponse.verifiedPlaintextCrc32c) {
    throw new Error('Encrypt: request corrupted in-transit');
  }
  if (
    crc32c.calculate(ciphertext) !==
    Number(encryptResponse.ciphertextCrc32c.value)
  ) {
    throw new Error('Encrypt: response corrupted in-transit');
  }

  console.log(`Ciphertext: ${ciphertext.toString('base64')}`);
  return ciphertext;
}

return encryptSymmetric();

PHP

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

use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
use Google\Cloud\Kms\V1\EncryptRequest;

function encrypt_symmetric(
    string $projectId = 'my-project',
    string $locationId = 'us-east1',
    string $keyRingId = 'my-key-ring',
    string $keyId = 'my-key',
    string $plaintext = '...'
) {
    // Create the Cloud KMS client.
    $client = new KeyManagementServiceClient();

    // Build the key name.
    $keyName = $client->cryptoKeyName($projectId, $locationId, $keyRingId, $keyId);

    // Call the API.
    $encryptRequest = (new EncryptRequest())
        ->setName($keyName)
        ->setPlaintext($plaintext);
    $encryptResponse = $client->encrypt($encryptRequest);
    printf('Ciphertext: %s' . PHP_EOL, $encryptResponse->getCiphertext());

    return $encryptResponse;
}

Python

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


# Import base64 for printing the ciphertext.
import base64

# Import the client library.
from google.cloud import kms


def encrypt_symmetric(
    project_id: str, location_id: str, key_ring_id: str, key_id: str, plaintext: str
) -> bytes:
    """
    Encrypt plaintext using a symmetric 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').
        plaintext (string): message to encrypt

    Returns:
        bytes: Encrypted ciphertext.

    """

    # Convert the plaintext to bytes.
    plaintext_bytes = plaintext.encode("utf-8")

    # Optional, but recommended: compute plaintext's CRC32C.
    # See crc32c() function defined below.
    plaintext_crc32c = crc32c(plaintext_bytes)

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

    # Build the key name.
    key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)

    # Call the API.
    encrypt_response = client.encrypt(
        request={
            "name": key_name,
            "plaintext": plaintext_bytes,
            "plaintext_crc32c": plaintext_crc32c,
        }
    )

    # Optional, but recommended: perform integrity verification on encrypt_response.
    # 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 encrypt_response.verified_plaintext_crc32c:
        raise Exception("The request sent to the server was corrupted in-transit.")
    if not encrypt_response.ciphertext_crc32c == crc32c(encrypt_response.ciphertext):
        raise Exception(
            "The response received from the server was corrupted in-transit."
        )
    # End integrity verification

    print(f"Ciphertext: {base64.b64encode(encrypt_response.ciphertext)}")
    return encrypt_response


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"
# plaintext  = "..."

# Require the library.
require "google/cloud/kms"

# Create the client.
client = Google::Cloud::Kms.key_management_service

# Build the parent key name.
key_name = client.crypto_key_path project:    project_id,
                                  location:   location_id,
                                  key_ring:   key_ring_id,
                                  crypto_key: key_id

# Call the API.
response = client.encrypt name: key_name, plaintext: plaintext
puts "Ciphertext: #{Base64.strict_encode64 response.ciphertext}"

API

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

JSON ๋ฐ REST API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ฝ˜ํ…์ธ ๋ฅผ base64๋กœ ์ธ์ฝ”๋”ฉํ•ด์•ผ Cloud KMS์—์„œ ์•”ํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•˜๋ ค๋ฉด POST ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์ ์ ˆํ•œ ํ”„๋กœ์ ํŠธ์™€ ํ‚ค ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ ์š”์ฒญ ๋ณธ๋ฌธ์˜ plaintext ํ•„๋“œ์— ์•”ํ˜ธํ™”ํ•  base64๋กœ ์ธ์ฝ”๋”ฉ๋œ ํ…์ŠคํŠธ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME:encrypt" \
  --request "POST" \
  --header "authorization: Bearer TOKEN" \
  --header "content-type: application/json" \
  --data "{\"plaintext\": \"PLAINTEXT_TO_ENCRYPT\"}"

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

  • PROJECT_ID: ์•”ํ˜ธํ™”์— ์‚ฌ์šฉํ•  ํ‚ค๋ง๊ณผ ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ID์ž…๋‹ˆ๋‹ค.
  • LOCATION: ํ‚ค๋ง์ด ํฌํ•จ๋œ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
  • KEY_RING: ์•”ํ˜ธํ™”์— ์‚ฌ์šฉํ•  ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์ž…๋‹ˆ๋‹ค.
  • KEY_NAME: ์•”ํ˜ธํ™”์— ์‚ฌ์šฉํ•  ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • PLAINTEXT_TO_ENCRYPT: ์•”ํ˜ธํ™”ํ•˜๋ ค๋Š” ์ผ๋ฐ˜ ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. encrypt ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ์ผ๋ฐ˜ ํ…์ŠคํŠธ๋ฅผ base64๋กœ ์ธ์ฝ”๋”ฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ base64๋กœ ์ธ์ฝ”๋”ฉ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ํŽ˜์ด๋กœ๋“œ์˜ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

{
  "plaintext": "U3VwZXIgc2VjcmV0IHRleHQgdGhhdCBtdXN0IGJlIGVuY3J5cHRlZAo=",
}

์•”ํ˜ธ๋ฌธ ๋ณตํ˜ธํ™”

์•”ํ˜ธํ™”๋œ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณตํ˜ธํ™”ํ•˜๋ ค๋ฉด ์ฝ˜ํ…์ธ  ์•”ํ˜ธํ™”์— ์‚ฌ์šฉํ•œ ํ‚ค์™€ ๋™์ผํ•œ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

gcloud

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

gcloud kms decrypt \
    --key KEY_NAME \
    --keyring KEY_RING \
    --location LOCATION  \
    --ciphertext-file FILE_TO_DECRYPT \
    --plaintext-file DECRYPTED_OUTPUT

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

  • KEY_NAME: ๋ณตํ˜ธํ™”์— ์‚ฌ์šฉํ•  ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • KEY_RING: ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • LOCATION: ํ‚ค๋ง์ด ํฌํ•จ๋œ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
  • FILE_TO_DECRYPT: ๋ณตํ˜ธํ™”ํ•˜๋ ค๋Š” ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.
  • DECRYPTED_OUTPUT: ๋ณตํ˜ธํ™”๋œ ์ถœ๋ ฅ์„ ์ €์žฅํ•  ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.

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

C#

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


using Google.Cloud.Kms.V1;
using Google.Protobuf;
using System.Text;

public class DecryptSymmetricSample
{
    public string DecryptSymmetric(
      string projectId = "my-project", string locationId = "us-east1", string keyRingId = "my-key-ring", string keyId = "my-key",
      byte[] ciphertext = null)
    {
        // Create the client.
        KeyManagementServiceClient client = KeyManagementServiceClient.Create();

        // Build the key name.
        CryptoKeyName keyName = new CryptoKeyName(projectId, locationId, keyRingId, keyId);

        // Call the API.
        DecryptResponse result = client.Decrypt(keyName, ByteString.CopyFrom(ciphertext));

        // Get the plaintext. Cryptographic plaintexts and ciphertexts are
        // always byte arrays.
        byte[] plaintext = result.Plaintext.ToByteArray();

        // Return the result.
        return Encoding.UTF8.GetString(plaintext);
    }
}

Go

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

import (
	"context"
	"fmt"
	"hash/crc32"
	"io"

	kms "cloud.google.com/go/kms/apiv1"
	"cloud.google.com/go/kms/apiv1/kmspb"
	"google.golang.org/protobuf/types/known/wrapperspb"
)

// decryptSymmetric will decrypt the input ciphertext bytes using the specified symmetric key.
func decryptSymmetric(w io.Writer, name string, ciphertext []byte) error {
	// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key"
	// ciphertext := []byte("...")  // result of a symmetric encryption call

	// 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()

	// Optional, but recommended: Compute ciphertext's CRC32C.
	crc32c := func(data []byte) uint32 {
		t := crc32.MakeTable(crc32.Castagnoli)
		return crc32.Checksum(data, t)
	}
	ciphertextCRC32C := crc32c(ciphertext)

	// Build the request.
	req := &kmspb.DecryptRequest{
		Name:             name,
		Ciphertext:       ciphertext,
		CiphertextCrc32C: wrapperspb.Int64(int64(ciphertextCRC32C)),
	}

	// Call the API.
	result, err := client.Decrypt(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to decrypt ciphertext: %w", err)
	}

	// 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
	if int64(crc32c(result.Plaintext)) != result.PlaintextCrc32C.Value {
		return fmt.Errorf("Decrypt: response corrupted in-transit")
	}

	fmt.Fprintf(w, "Decrypted plaintext: %s", result.Plaintext)
	return nil
}

Java

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

import com.google.cloud.kms.v1.CryptoKeyName;
import com.google.cloud.kms.v1.DecryptResponse;
import com.google.cloud.kms.v1.KeyManagementServiceClient;
import com.google.protobuf.ByteString;
import java.io.IOException;

public class DecryptSymmetric {

  public void decryptSymmetric() 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 keyId = "my-key";
    byte[] ciphertext = null;
    decryptSymmetric(projectId, locationId, keyRingId, keyId, ciphertext);
  }

  // Decrypt data that was encrypted using a symmetric key.
  public void decryptSymmetric(
      String projectId, String locationId, String keyRingId, String keyId, byte[] ciphertext)
      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 key version name from the project, location, key ring, and
      // key.
      CryptoKeyName keyName = CryptoKeyName.of(projectId, locationId, keyRingId, keyId);

      // Decrypt the response.
      DecryptResponse response = client.decrypt(keyName, ByteString.copyFrom(ciphertext));
      System.out.printf("Plaintext: %s%n", response.getPlaintext().toStringUtf8());
    }
  }
}

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';
// Ciphertext must be either a Buffer object or a base-64 encoded string
// const ciphertext = Buffer.from('...');

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

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

// Build the key name
const keyName = client.cryptoKeyPath(projectId, locationId, keyRingId, keyId);

// Optional, but recommended: compute ciphertext's CRC32C.
const crc32c = require('fast-crc32c');
const ciphertextCrc32c = crc32c.calculate(ciphertext);

async function decryptSymmetric() {
  const [decryptResponse] = await client.decrypt({
    name: keyName,
    ciphertext: ciphertext,
    ciphertextCrc32c: {
      value: ciphertextCrc32c,
    },
  });

  // Optional, but recommended: perform integrity verification on decryptResponse.
  // 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 (
    crc32c.calculate(decryptResponse.plaintext) !==
    Number(decryptResponse.plaintextCrc32c.value)
  ) {
    throw new Error('Decrypt: response corrupted in-transit');
  }

  const plaintext = decryptResponse.plaintext.toString();

  console.log(`Plaintext: ${plaintext}`);
  return plaintext;
}

return decryptSymmetric();

PHP

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

use Google\Cloud\Kms\V1\Client\KeyManagementServiceClient;
use Google\Cloud\Kms\V1\DecryptRequest;

function decrypt_symmetric(
    string $projectId = 'my-project',
    string $locationId = 'us-east1',
    string $keyRingId = 'my-key-ring',
    string $keyId = 'my-key',
    string $ciphertext = '...'
) {
    // Create the Cloud KMS client.
    $client = new KeyManagementServiceClient();

    // Build the key name.
    $keyName = $client->cryptoKeyName($projectId, $locationId, $keyRingId, $keyId);

    // Call the API.
    $decryptRequest = (new DecryptRequest())
        ->setName($keyName)
        ->setCiphertext($ciphertext);
    $decryptResponse = $client->decrypt($decryptRequest);
    printf('Plaintext: %s' . PHP_EOL, $decryptResponse->getPlaintext());

    return $decryptResponse;
}

Python

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

from google.cloud import kms


def decrypt_symmetric(
    project_id: str, location_id: str, key_ring_id: str, key_id: str, ciphertext: bytes
) -> kms.DecryptResponse:
    """
    Decrypt the ciphertext using the symmetric 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').
        ciphertext (bytes): Encrypted bytes to decrypt.

    Returns:
        DecryptResponse: Response including plaintext.

    """

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

    # Build the key name.
    key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)

    # Optional, but recommended: compute ciphertext's CRC32C.
    # See crc32c() function defined below.
    ciphertext_crc32c = crc32c(ciphertext)

    # Call the API.
    decrypt_response = client.decrypt(
        request={
            "name": key_name,
            "ciphertext": ciphertext,
            "ciphertext_crc32c": ciphertext_crc32c,
        }
    )

    # Optional, but recommended: perform integrity verification on decrypt_response.
    # 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 decrypt_response.plaintext_crc32c == crc32c(decrypt_response.plaintext):
        raise Exception(
            "The response received from the server was corrupted in-transit."
        )
    # End integrity verification

    print(f"Plaintext: {decrypt_response.plaintext!r}")
    return decrypt_response


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"
# ciphertext  = "..."

# Require the library.
require "google/cloud/kms"

# Create the client.
client = Google::Cloud::Kms.key_management_service

# Build the parent key name.
key_name = client.crypto_key_path project:    project_id,
                                  location:   location_id,
                                  key_ring:   key_ring_id,
                                  crypto_key: key_id

# Call the API.
response = client.decrypt name: key_name, ciphertext: ciphertext
puts "Plaintext: #{response.plaintext}"

API

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

Cloud KMS์—์„œ JSON์œผ๋กœ ๋ฐ˜ํ™˜๋œ ๋ณตํ˜ธํ™”๋œ ํ…์ŠคํŠธ๋Š” base64๋กœ ์ธ์ฝ”๋”ฉ๋ฉ๋‹ˆ๋‹ค.

์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณตํ˜ธํ™”ํ•˜๋ ค๋ฉด POST ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์ ์ ˆํ•œ ํ”„๋กœ์ ํŠธ์™€ ํ‚ค ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ ์š”์ฒญ ๋ณธ๋ฌธ์˜ ciphertext ํ•„๋“œ์— ๋ณตํ˜ธํ™”ํ•  ์•”ํ˜ธํ™”๋œ ํ…์ŠคํŠธ(์•”ํ˜ธ๋ฌธ์ด๋ผ๊ณ ๋„ ํ•จ)๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

curl "https://cloudkms.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME:decrypt" \
  --request "POST" \
  --header "authorization: Bearer TOKEN" \
  --header "content-type: application/json" \
  --data "{\"ciphertext\": \"ENCRYPTED_DATA\"}"

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

  • PROJECT_ID: ๋ณตํ˜ธํ™”์— ์‚ฌ์šฉํ•  ํ‚ค๋ง๊ณผ ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ID์ž…๋‹ˆ๋‹ค.
  • LOCATION: ํ‚ค๋ง์ด ํฌํ•จ๋œ Cloud KMS ์œ„์น˜์ž…๋‹ˆ๋‹ค.
  • KEY_RING: ๋ณตํ˜ธํ™”์— ์‚ฌ์šฉํ•  ํ‚ค๊ฐ€ ํฌํ•จ๋œ ํ‚ค๋ง์ž…๋‹ˆ๋‹ค.
  • KEY_NAME: ๋ณตํ˜ธํ™”์— ์‚ฌ์šฉํ•  ํ‚ค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • ENCRYPTED_DATA: ๋ณตํ˜ธํ™”ํ•˜๋ ค๋Š” ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ base64๋กœ ์ธ์ฝ”๋”ฉ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ํŽ˜์ด๋กœ๋“œ์˜ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

{
  "ciphertext": "CiQAhMwwBo61cHas7dDgifrUFs5zNzBJ2uZtVFq4ZPEl6fUVT4kSmQ...",
}

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

์•Œ๋ ค์ง„ ์ œํ•œ์‚ฌํ•ญ

  • ์‚ฌ์šฉ์ž ์ œ๊ณต ์ผ๋ฐ˜ ํ…์ŠคํŠธ์™€ ์•”ํ˜ธ๋ฌธ์—์„œ ๋ฉ”์‹œ์ง€ ํฌ๊ธฐ๋Š” ์ถ”๊ฐ€ ์ธ์ฆ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜์—ฌ 8KiB๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค(์ด์™€ ๋‹ค๋ฅด๊ฒŒ Cloud KMS ์†Œํ”„ํŠธ์›จ์–ด ํ‚ค์˜ ๊ฒฝ์šฐ 64KiB).

  • ํŠน์ • ๋‹ค์ค‘ ๋˜๋Š” ์ด์ค‘ ๋ฆฌ์ „์—์„œ๋Š” Cloud HSM์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Cloud HSM์— ์ง€์›๋˜๋Š” ๋ฆฌ์ „์„ ์ฐธ์กฐํ•˜์„ธ์š”.

  • ๋‹ค๋ฅธ Google Cloud ์„œ๋น„์Šค์—์„œ ๊ณ ๊ฐ ๊ด€๋ฆฌ ์•”ํ˜ธํ™” ํ‚ค(CMEK) ํ†ตํ•ฉ๊ณผ ํ•จ๊ป˜ Cloud HSM ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์„œ๋น„์Šค์— ์‚ฌ์šฉํ•˜๋Š” ์œ„์น˜๋Š” Cloud HSM ํ‚ค์˜ ์œ„์น˜์™€ ์ •ํ™•ํ•˜๊ฒŒ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฆฌ์ „, ์ด์ค‘ ๋ฆฌ์ „, ๋ฉ€ํ‹ฐ ๋ฆฌ์ „ ์œ„์น˜์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

    CMEK ํ†ตํ•ฉ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ €์žฅ ๋ฐ์ดํ„ฐ ์•”ํ˜ธํ™” ์„น์…˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

  • Cloud KMS ์†Œํ”„ํŠธ์›จ์–ด ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์— ๋น„ํ•ด ํ˜„์žฌ Cloud HSM์— ์ €์žฅ๋œ ๋น„๋Œ€์นญ ํ‚ค์— ๋Œ€ํ•œ ํ‚ค ์ž‘์—…์—์„œ ์ง€์—ฐ ์‹œ๊ฐ„์ด ํฌ๊ฒŒ ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒ ์–ด๋ฉ”ํƒˆ ๋ž™ HSM

Google Cloud ๋Š” ๋‹จ์ผ ํ…Œ๋„Œ์‹œ์™€ ๊ฐ™์€ ์ถ”๊ฐ€ HSM ์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฒ ์–ด๋ฉ”ํƒˆ ๋ž™ HSM์€ ๊ณ ๊ฐ์ด Google์—์„œ ์ œ๊ณตํ•œ ๊ณต๊ฐ„์—์„œ ์ž์ฒด HSM์„ ํ˜ธ์ŠคํŒ…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ•ด๋‹น ๊ณ„์ • ๋‹ด๋‹น์ž์—๊ฒŒ ๋ฌธ์˜ํ•˜์„ธ์š”.