Importa una clave unida de forma manual

Importa una clave a Cloud KMS que hayas unido de forma manual.

Explora más

Para obtener documentación en la que se incluye esta muestra de código, consulta lo siguiente:

Muestra de código

Go

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud KMS, consulta las bibliotecas cliente de Cloud KMS.

Para autenticarte en Cloud KMS, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import (
	"context"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io"

	kms "cloud.google.com/go/kms/apiv1"
	"cloud.google.com/go/kms/apiv1/kmspb"
	"github.com/google/tink/go/kwp/subtle"
)

// importManuallyWrappedKey wraps key material and imports it into KMS.
func importManuallyWrappedKey(w io.Writer, importJobName, cryptoKeyName string) error {
	// importJobName := "projects/PROJECT_ID/locations/global/keyRings/my-key-ring/importJobs/my-import-job"
	// cryptoKeyName := "projects/PROJECT_ID/locations/global/keyRings/my-key-ring/cryptoKeys/my-imported-key"

	// Generate a ECDSA keypair, and format the private key as PKCS #8 DER.
	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		return fmt.Errorf("failed to generate keypair: %w", err)
	}
	keyBytes, err := x509.MarshalPKCS8PrivateKey(key)
	if err != nil {
		return fmt.Errorf("failed to format private key: %w", err)
	}

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

	// Generate a temporary 32-byte key for AES-KWP and wrap the key material.
	kwpKey := make([]byte, 32)
	if _, err := rand.Read(kwpKey); err != nil {
		return fmt.Errorf("failed to generate AES-KWP key: %w", err)
	}
	kwp, err := subtle.NewKWP(kwpKey)
	if err != nil {
		return fmt.Errorf("failed to create KWP cipher: %w", err)
	}
	wrappedTarget, err := kwp.Wrap(keyBytes)
	if err != nil {
		return fmt.Errorf("failed to wrap target key with KWP: %w", err)
	}

	// Retrieve the public key from the import job.
	importJob, err := client.GetImportJob(ctx, &kmspb.GetImportJobRequest{
		Name: importJobName,
	})
	if err != nil {
		return fmt.Errorf("failed to retrieve import job: %w", err)
	}
	pubBlock, _ := pem.Decode([]byte(importJob.PublicKey.Pem))
	pubAny, err := x509.ParsePKIXPublicKey(pubBlock.Bytes)
	if err != nil {
		return fmt.Errorf("failed to parse import job public key: %w", err)
	}
	pub, ok := pubAny.(*rsa.PublicKey)
	if !ok {
		return fmt.Errorf("unexpected public key type %T, want *rsa.PublicKey", pubAny)
	}

	// Wrap the KWP key using the import job key.
	wrappedWrappingKey, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, pub, kwpKey, nil)
	if err != nil {
		return fmt.Errorf("failed to wrap KWP key: %w", err)
	}

	// Concatenate the wrapped KWP key and the wrapped target key.
	combined := append(wrappedWrappingKey, wrappedTarget...)

	// Build the request.
	req := &kmspb.ImportCryptoKeyVersionRequest{
		Parent:     cryptoKeyName,
		ImportJob:  importJobName,
		Algorithm:  kmspb.CryptoKeyVersion_EC_SIGN_P256_SHA256,
		WrappedKey: combined,
	}

	// Call the API.
	result, err := client.ImportCryptoKeyVersion(ctx, req)
	if err != nil {
		return fmt.Errorf("failed to import crypto key version: %w", err)
	}
	fmt.Fprintf(w, "Created crypto key version: %s\n", result.Name)
	return nil
}

Java

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud KMS, consulta las bibliotecas cliente de Cloud KMS.

Para autenticarte en Cloud KMS, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import com.google.cloud.kms.v1.CryptoKeyName;
import com.google.cloud.kms.v1.CryptoKeyVersion;
import com.google.cloud.kms.v1.ImportCryptoKeyVersionRequest;
import com.google.cloud.kms.v1.ImportJob;
import com.google.cloud.kms.v1.ImportJobName;
import com.google.cloud.kms.v1.KeyManagementServiceClient;
import com.google.crypto.tink.subtle.Kwp;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;

public class ImportManuallyWrappedKey {

  public void importManuallyWrappedKey() throws GeneralSecurityException, 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 cryptoKeyId = "my-crypto-key";
    String importJobId = "my-import-job";
    importManuallyWrappedKey(projectId, locationId, keyRingId, cryptoKeyId, importJobId);
  }

  // Generates and imports local key material into Cloud KMS.
  public void importManuallyWrappedKey(
      String projectId, String locationId, String keyRingId, String cryptoKeyId, String importJobId)
      throws GeneralSecurityException, IOException {

    // Generate a new ECDSA keypair, and format the private key as PKCS #8 DER.
    KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
    generator.initialize(new ECGenParameterSpec("secp256r1"));
    KeyPair kp = generator.generateKeyPair();
    byte[] privateBytes = kp.getPrivate().getEncoded();

    // 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 crypto key and import job names from the project, location,
      // key ring, and ID.
      final CryptoKeyName cryptoKeyName =
          CryptoKeyName.of(projectId, locationId, keyRingId, cryptoKeyId);
      final ImportJobName importJobName =
          ImportJobName.of(projectId, locationId, keyRingId, importJobId);

      // Generate a temporary 32-byte key for AES-KWP and wrap the key material.
      byte[] kwpKey = new byte[32];
      new SecureRandom().nextBytes(kwpKey);
      Kwp kwp = new Kwp(kwpKey);
      final byte[] wrappedTargetKey = kwp.wrap(privateBytes);

      // Retrieve the public key from the import job.
      ImportJob importJob = client.getImportJob(importJobName);
      String publicKeyStr = importJob.getPublicKey().getPem();
      // Manually convert PEM to DER. :-(
      publicKeyStr = publicKeyStr.replace("-----BEGIN PUBLIC KEY-----", "");
      publicKeyStr = publicKeyStr.replace("-----END PUBLIC KEY-----", "");
      publicKeyStr = publicKeyStr.replaceAll("\n", "");
      byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
      PublicKey publicKey =
          KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(publicKeyBytes));

      // Wrap the KWP key using the import job key.
      Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
      cipher.init(
          Cipher.ENCRYPT_MODE,
          publicKey,
          new OAEPParameterSpec(
              "SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT));
      byte[] wrappedWrappingKey = cipher.doFinal(kwpKey);

      // Concatenate the wrapped KWP key and the wrapped target key.
      ByteString combinedWrappedKeys =
          ByteString.copyFrom(wrappedWrappingKey).concat(ByteString.copyFrom(wrappedTargetKey));

      // Import the wrapped key material.
      CryptoKeyVersion version =
          client.importCryptoKeyVersion(
              ImportCryptoKeyVersionRequest.newBuilder()
                  .setParent(cryptoKeyName.toString())
                  .setImportJob(importJobName.toString())
                  .setAlgorithm(CryptoKeyVersion.CryptoKeyVersionAlgorithm.EC_SIGN_P256_SHA256)
                  .setRsaAesWrappedKey(combinedWrappedKeys)
                  .build());

      System.out.printf("Imported: %s%n", version.getName());
    }
  }
}

Node.js

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud KMS, consulta las bibliotecas cliente de Cloud KMS.

Para autenticarte en Cloud KMS, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

//
// TODO(developer): Uncomment these variables before running the sample.
//
// const projectId = 'my-project';
// const locationId = 'us-east1';
// const keyRingId = 'my-key-ring';
// const cryptoKeyId = 'my-imported-key';
// const importJobId = 'my-import-job';

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

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

// Build the crypto key and importjob resource names
const cryptoKeyName = client.cryptoKeyPath(
  projectId,
  locationId,
  keyRingId,
  cryptoKeyId
);
const importJobName = client.importJobPath(
  projectId,
  locationId,
  keyRingId,
  importJobId
);

async function wrapAndImportKey() {
  // Generate a 32-byte key to import.
  const crypto = require('crypto');
  const targetKey = crypto.randomBytes(32);

  const [importJob] = await client.getImportJob({name: importJobName});

  // Wrap the target key using the import job key
  const wrappedTargetKey = crypto.publicEncrypt(
    {
      key: importJob.publicKey.pem,
      oaepHash: 'sha256',
      padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
    },
    targetKey
  );

  // Import the target key version
  const [version] = await client.importCryptoKeyVersion({
    parent: cryptoKeyName,
    importJob: importJobName,
    algorithm: 'GOOGLE_SYMMETRIC_ENCRYPTION',
    wrappedKey: wrappedTargetKey,
  });

  console.log(`Imported key version: ${version.name}`);
  return version;
}

return wrapAndImportKey();

Python

Para obtener información sobre cómo instalar y usar la biblioteca cliente de Cloud KMS, consulta las bibliotecas cliente de Cloud KMS.

Para autenticarte en Cloud KMS, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import os

# Import the client library and Python standard cryptographic libraries.
from cryptography.hazmat import backends
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import keywrap
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric import padding
from google.cloud import kms

def import_manually_wrapped_key(
    project_id: str,
    location_id: str,
    key_ring_id: str,
    crypto_key_id: str,
    import_job_id: str,
) -> None:
    """
    Generates and imports local key material to 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').
        crypto_key_id (string): ID of the key to import (e.g. 'my-asymmetric-signing-key').
        import_job_id (string): ID of the import job (e.g. 'my-import-job').
    """

    # Generate some key material in Python and format it in PKCS #8 DER as
    # required by Google Cloud KMS.
    key = ec.generate_private_key(ec.SECP256R1, backends.default_backend())
    formatted_key = key.private_bytes(
        serialization.Encoding.DER,
        serialization.PrivateFormat.PKCS8,
        serialization.NoEncryption(),
    )

    print(f"Generated key bytes: {formatted_key!r}")

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

    # Retrieve the fully-qualified crypto_key and import_job string.
    crypto_key_name = client.crypto_key_path(
        project_id, location_id, key_ring_id, crypto_key_id
    )
    import_job_name = client.import_job_path(
        project_id, location_id, key_ring_id, import_job_id
    )

    # Generate a temporary 32-byte key for AES-KWP and wrap the key material.
    kwp_key = os.urandom(32)
    wrapped_target_key = keywrap.aes_key_wrap_with_padding(
        kwp_key, formatted_key, backends.default_backend()
    )

    # Retrieve the public key from the import job.
    import_job = client.get_import_job(name=import_job_name)
    import_job_pub = serialization.load_pem_public_key(
        bytes(import_job.public_key.pem, "UTF-8"), backends.default_backend()
    )

    # Wrap the KWP key using the import job key.
    wrapped_kwp_key = import_job_pub.encrypt(
        kwp_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA1()),
            algorithm=hashes.SHA1(),
            label=None,
        ),
    )

    # Import the wrapped key material.
    client.import_crypto_key_version(
        {
            "parent": crypto_key_name,
            "import_job": import_job_name,
            "algorithm": kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.EC_SIGN_P256_SHA256,
            "rsa_aes_wrapped_key": wrapped_kwp_key + wrapped_target_key,
        }
    )

    print(f"Imported: {import_job.name}")

¿Qué sigue?

Para buscar y filtrar muestras de código para otros productos de Google Cloud, consulta el navegador de muestra de Google Cloud.