שליפה של מפתח ציבורי

בדף הזה מוסבר איך לאחזר את החלק של המפתח הציבורי בגרסה של מפתח אסימטרי שמופעל.

הפורמט של המפתח הציבורי תלוי בסוג האלגוריתם: פוסט-קוונטי (PQC) או קונבנציונלי:

  • עבור אלגוריתמים שאינם PQC, פורמט ברירת המחדל של המפתח הציבורי הוא Privacy-enhanced Electronic Mail (PEM). אפשר גם לאחזר מפתחות ציבוריים שאינם PQC בפורמט Distinguished Encoding Rules ‏ (DER). מידע נוסף זמין ב-RFC 7468, במיוחד בקטעים General Considerations (שיקולים כלליים) ו-Textual Encoding of Subject Public Key Info (קידוד טקסטואלי של מידע על מפתח ציבורי של נושא).

  • עבור אלגוריתמים של PQC שתוקננו על ידי NIST (גרסת Preview), אפשר לאחזר את המפתח הציבורי בפורמט שמופיע בתקני ה-PCQ של NIST לאותו אלגוריתם. מידע נוסף זמין במאמרים בנושא FIPS-203,‏ FIPS-204 ו-FIPS-205. הפורמטים PEM ו-DER נתמכים רק במפתחות ML-DSA.

  • ב-X-Wing, אפשר לאחזר את המפתח הציבורי בפורמט הבייטים הגולמי שצוין בתקן X-Wing. אין תמיכה במפתחות בפורמטים PEM ו-DER.

התפקידים הנדרשים

כדי לקבל את ההרשאות שנדרשות בשביל לאחזר מפתח ציבורי, צריך לבקש מהאדמין לתת לכם את תפקיד ה-IAM‏ Cloud KMS CryptoKey Public Key Viewer ‏ (roles/cloudkms.publicKeyViewer) במפתח או במשאב אב. כדי לקרוא הסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

זהו תפקיד שמוגדר מראש וכולל את ההרשאות שנדרשות לאחזור מפתח ציבורי. כדי לראות בדיוק אילו הרשאות נדרשות, אפשר להרחיב את הקטע ההרשאות הנדרשות:

ההרשאות הנדרשות

כדי לאחזר מפתח ציבורי, נדרשות ההרשאות הבאות:

  • cloudkms.cryptoKeyVersions.viewPublicKey
  • cloudkms.locations.get
  • cloudkms.locations.list
  • resourcemanager.projects.get

יכול להיות שתקבלו את ההרשאות האלה באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש אחרים.

שליפה של מפתח ציבורי

אפשר לציין את הפורמט שבו רוצים לאחזר את המפתח הציבורי. אם מציינים את הפורמט, המפתח יוחזר בפורמט שצוין בשדה public_key של התשובה. אחרת, הוא מוחזר בשדה pem של התשובה.

כדי להוריד את המפתח הציבורי לגרסה של מפתח אסימטרי שמופעל:

המסוף

  1. נכנסים לדף Key Management במסוף Google Cloud .

    כניסה אל Key Management

  2. לוחצים על השם של אוסף המפתחות שמכיל את המפתח האסימטרי שרוצים לאחזר את המפתח הציבורי שלו.

  3. לוחצים על שם המפתח שרוצים לאחזר את המפתח הציבורי שלו.

  4. בשורה שמתאימה לגרסת המפתח שרוצים לאחזר את המפתח הציבורי שלה, לוחצים על הצגת פרטים נוספים .

  5. לוחצים על קבלת מפתח ציבורי.

  6. המפתח הציבורי מוצג בהנחיה. אפשר להעתיק את המפתח הציבורי ללוח. כדי להוריד את המפתח הציבורי, לוחצים על הורדה.

אם האפשרות Get public key לא מופיעה, צריך לוודא את הדברים הבאים:

  • המפתח הוא מפתח אסימטרי.
  • גרסת המפתח מופעלת.
  • יש לך הרשאה מסוג 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: הפורמט שבו רוצים לייצא את המפתח הציבורי. כדי להשתמש באלגוריתמים של NIST PQC (Preview), משתמשים ב-nist-pqc, וכדי להשתמש ב-X-Wing, משתמשים ב-xwing-raw-bytes. לכל שאר המפתחות, אפשר להשתמש בערך pem, der או להשמיט את הפרמטר הזה.
  • OUTPUT_FILE_PATH: הנתיב שבו רוצים לשמור את קובץ המפתח הציבורי, לדוגמה public-key.pub.

כדי לקבל מידע על כל הדגלים והערכים האפשריים, מריצים את הפקודה עם הדגל --help.

C#

כדי להריץ את הקוד הזה, קודם צריך להגדיר סביבת פיתוח בשפת C# ‎ ולהתקין את ה-SDK של Cloud KMS C# ‎.


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

כדי להריץ את הקוד הזה, קודם צריך להגדיר סביבת פיתוח ב-Java ולהתקין את Cloud KMS Java 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

כדי להריץ את הקוד הזה, קודם צריך לקרוא על שימוש ב-PHP ב- Google Cloud ולהתקין את 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.

שולפים את המפתח הציבורי באמצעות קריאה ל-method‏ 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: מזהה הפרויקט שמכיל את מחזיק המפתחות.
  • LOCATION: המיקום ב-Cloud KMS שבו נמצא אוסף המפתחות.
  • KEY_RING: השם של אוסף המפתחות שמכיל את המפתח.
  • KEY_NAME: השם של המפתח.
  • KEY_VERSION: מספר גרסת המפתח.
  • PUBLIC_KEY_FORMAT: הפורמט שבו רוצים לייצא את המפתח הציבורי. עבור אלגוריתמים של PQC ‏(Preview), משתמשים ב-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"
}

עבור אלגוריתם PQC עם פורמט מפתח ציבורי NIST_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"
}