Volver a encriptar datos

En este tema se muestra cómo volver a cifrar datos con una clave simétrica de Cloud Key Management Service. Puedes adaptar estos ejemplos para claves asimétricas. Si sospechas que se está usando una clave sin autorización, debes volver a encriptar los datos protegidos por esa clave y, a continuación, inhabilitar o programar la eliminación de la versión anterior de la clave.

Antes de empezar

Este caso requiere las siguientes condiciones.

  • Ya has encriptado datos con Cloud KMS.

  • La versión de la clave utilizada para el cifrado no está inhabilitada, programada para su destrucción ni destruida. Esta versión de la clave se usa para descifrar los datos cifrados.

  • Ya has cambiado las claves. La rotación de claves crea una nueva versión de clave principal. Usa la nueva versión de la clave principal para volver a cifrar los datos.

Volver a encriptar datos con claves asimétricas

En los ejemplos de este tema se muestra cómo volver a cifrar datos con una clave simétrica. Cuando usas una clave simétrica, Cloud KMS deduce automáticamente la versión de la clave que se debe usar para el desencriptado. Cuando usas una clave asimétrica, debes especificar la versión de la clave.

El flujo de trabajo para volver a encriptar datos con claves asimétricas es similar al que se describe en este tema.

Flujo de trabajo para volver a cifrar datos

Siga estos pasos para volver a cifrar los datos y para inhabilitar o programar la destrucción de la versión de la clave que se usó para el cifrado original.

  1. Descifrar los datos con la versión anterior de la clave

  2. Vuelve a cifrar los datos con la nueva versión de la clave principal

  3. Inhabilitar o programar la destrucción de la versión de clave anterior

Descifrar los datos con la versión anterior de la clave

Cloud KMS usa automáticamente la versión de clave correcta para desencriptar datos, siempre que la versión de clave no esté inhabilitada, programada para su destrucción o destruida. En los siguientes ejemplos se muestra cómo descifrar los datos. Es el mismo código de descifrado que se usa en Cifrado y descifrado.

gcloud

Para usar Cloud KMS en la línea de comandos, primero instala o actualiza a la versión más reciente de la CLI de Google Cloud.

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

Haz los cambios siguientes:

  • KEY_NAME: el nombre de la clave que quieras usar para el descifrado.
  • KEY_RING: el nombre del conjunto de claves que contiene la clave.
  • LOCATION: la ubicación de Cloud KMS que contiene el conjunto de claves.
  • FILE_TO_DECRYPT: la ruta al archivo que quieres descifrar.
  • DECRYPTED_OUTPUT: la ruta en la que quieres guardar el resultado descifrado.

Para obtener información sobre todas las marcas y los valores posibles, ejecuta el comando con la marca --help.

C#

Para ejecutar este código, primero debes configurar un entorno de desarrollo de C# e instalar el SDK de Cloud KMS para C#.


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

Para ejecutar este código, primero debes configurar un entorno de desarrollo de Go e instalar el SDK de Go de Cloud KMS.

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

Para ejecutar este código, primero debes configurar un entorno de desarrollo de Java e instalar el SDK de Java de Cloud KMS.

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