Chiffrer et déchiffrer des données avec une clé asymétrique

Vous trouverez dans cette rubrique des informations sur la création et l'utilisation d'une clé RSA pour le chiffrement asymétrique. Si vous souhaitez utiliser des clés asymétriques pour créer et valider des signatures, consultez la page Créer et valider des signatures numériques. Si vous souhaitez utiliser des clés symétriques pour le chiffrement et le déchiffrement, consultez la page Chiffrer et déchiffrer des données.

Le chiffrement asymétrique utilise la partie clé publique de la clé asymétrique, et le déchiffrement utilise la partie clé privée. Une fonctionnalité de Cloud Key Management Service permet de récupérer la clé publique, et une autre fonctionnalité permet de déchiffrer le texte qui a été chiffré avec la clé publique. Cloud KMS n'autorise pas l'accès direct à la clé privée.

Avant de commencer

  • Cette rubrique fournit des exemples qui s'exécutent sur la ligne de commande. Pour simplifier l'utilisation des exemples, utilisez Cloud Shell. L'exemple de chiffrement utilise OpenSSL, pré-installé sur Cloud Shell.

  • Créez une clé asymétrique dotée de l'objectif ASYMMETRIC_DECRYPT. Pour savoir quels algorithmes sont compatibles avec ASYMMETRIC_DECRYPT, consultez la page Algorithmes de chiffrement asymétrique. Vous ne pouvez pas suivre cette procédure avec une clé dotée de l'objectif ASYMMETRIC_SIGN.

  • Si vous souhaitez utiliser la ligne de commande, installez OpenSSL si vous ne l'avez pas déjà. Si vous utilisez Cloud Shell, OpenSSL est déjà installé.

  • Utilisateurs de macOS:la version d'OpenSSL installée sur macOS n'est pas compatible avec les options utilisées pour déchiffrer les données dans cette rubrique. Pour suivre ces étapes sur macOS, installez OpenSSL à partir de Homebrew.

Contrôle des accès à la clé

  • Pour un utilisateur ou un service qui récupère la clé publique, accordez l'autorisation cloudkms.cryptoKeyVersions.viewPublicKey sur la clé asymétrique. La clé publique est obligatoire pour chiffrer les données.

  • Pour un utilisateur ou un service qui déchiffre des données préalablement chiffrées avec la clé publique, accordez l'autorisation cloudkms.cryptoKeyVersions.useToDecrypt sur la clé asymétrique.

Pour en savoir plus sur les autorisations et les rôles dans Cloud KMS, consultez la page Autorisations et rôles.

Chiffrer des données

Pour chiffrer des données à l'aide d'une clé de chiffrement asymétrique, récupérez la clé publique et utilisez-la pour chiffrer les données.

gcloud

Dans cet exemple, OpenSSL doit être installé sur votre système local.

Télécharger la clé publique

Téléchargez la clé publique :

gcloud kms keys versions get-public-key key-version \
    --key key \
    --keyring key-ring \
    --location location  \
    --output-file public-key-path

Remplacez key-version par la version de clé contenant la clé publique. Remplacez key par le nom de la clé. Remplacez key-ring par le nom du trousseau de clés où se trouve la clé. Remplacez location par l'emplacement Cloud KMS du trousseau de clés. Remplacez public-key-path par l'emplacement pour enregistrer la clé publique sur le système local.

Chiffrer des données

Chiffrez les données en utilisant la clé publique que vous venez de télécharger, puis enregistrez le résultat dans un fichier :

openssl pkeyutl -in cleartext-data-input-file \
    -encrypt \
    -pubin \
    -inkey public-key-path \
    -pkeyopt rsa_padding_mode:oaep \
    -pkeyopt rsa_oaep_md:sha256 \
    -pkeyopt rsa_mgf1_md:sha256 \
    > encrypted-data-output-file
  • Remplacez cleartext-data-input-file par le chemin d'accès et le nom du fichier à chiffrer.

  • Remplacez public-key-path par le chemin d'accès et le nom du fichier où vous avez téléchargé la clé publique.

  • Remplacez encrypted-data-output-file par le chemin d'accès et le nom du fichier pour enregistrer les données chiffrées.

C#

Pour exécuter ce code, commencez par configurer un environnement de développement C#, puis installez le SDK Cloud KMS pour C#.


using Google.Cloud.Kms.V1;
using System;
using System.Security.Cryptography;
using System.Text;

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

        // Build the key version name.
        CryptoKeyVersionName keyVersionName = new CryptoKeyVersionName(projectId, locationId, keyRingId, keyId, keyVersionId);

        // Get the public key.
        PublicKey publicKey = client.GetPublicKey(keyVersionName);

        // Split the key into blocks and base64-decode the PEM parts.
        string[] blocks = publicKey.Pem.Split("-", StringSplitOptions.RemoveEmptyEntries);
        byte[] pem = Convert.FromBase64String(blocks[1]);

        // Create a new RSA key.
        RSA rsa = RSA.Create();
        rsa.ImportSubjectPublicKeyInfo(pem, out _);

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

        // Encrypt the data.
        byte[] ciphertext = rsa.Encrypt(plaintext, RSAEncryptionPadding.OaepSHA256);
        return ciphertext;
    }
}

Go

Pour utiliser Cloud KMS sur la ligne de commande, commencez par installer ou mettre à jour la dernière version de Google Cloud CLI.

import (
	"context"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io"

	kms "cloud.google.com/go/kms/apiv1"
	"cloud.google.com/go/kms/apiv1/kmspb"
)

// encryptAsymmetric encrypts data on your local machine using an
// 'RSA_DECRYPT_OAEP_2048_SHA256' public key retrieved from Cloud KMS.
func encryptAsymmetric(w io.Writer, name string, message string) error {
	// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key/cryptoKeyVersions/123"
	// 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()

	// Retrieve the public key from Cloud KMS. This is the only operation that
	// involves Cloud KMS. The remaining operations take place on your local
	// machine.
	response, err := client.GetPublicKey(ctx, &kmspb.GetPublicKeyRequest{
		Name: name,
	})
	if err != nil {
		return fmt.Errorf("failed to get public key: %w", err)
	}

	// Parse the public key. Note, this example assumes the public key is in the
	// RSA format.
	block, _ := pem.Decode([]byte(response.Pem))
	publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return fmt.Errorf("failed to parse public key: %w", err)
	}
	rsaKey, ok := publicKey.(*rsa.PublicKey)
	if !ok {
		return fmt.Errorf("public key is not rsa")
	}

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

	// Encrypt data using the RSA public key.
	ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, rsaKey, plaintext, nil)
	if err != nil {
		return fmt.Errorf("rsa.EncryptOAEP: %w", err)
	}
	fmt.Fprintf(w, "Encrypted ciphertext: %s", ciphertext)
	return nil
}

Java

Pour exécuter ce code, commencez par configurer un environnement de développement Java et installez le SDK Cloud KMS pour Java.

import com.google.cloud.kms.v1.CryptoKeyVersionName;
import com.google.cloud.kms.v1.KeyManagementServiceClient;
import com.google.cloud.kms.v1.PublicKey;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.stream.Collectors;
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;

public class EncryptAsymmetric {

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

  // Encrypt data that was encrypted using the public key component of the given
  // key version.
  public void encryptAsymmetric(
      String projectId,
      String locationId,
      String keyRingId,
      String keyId,
      String keyVersionId,
      String plaintext)
      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);

      // Convert the public PEM key to a DER key (see helper below).
      byte[] derKey = convertPemToDer(publicKey.getPem());
      X509EncodedKeySpec keySpec = new X509EncodedKeySpec(derKey);
      java.security.PublicKey rsaKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);

      // Encrypt plaintext for the 'RSA_DECRYPT_OAEP_2048_SHA256' key.
      // For other key algorithms:
      // https://docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html
      Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
      OAEPParameterSpec oaepParams =
          new OAEPParameterSpec(
              "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
      cipher.init(Cipher.ENCRYPT_MODE, rsaKey, oaepParams);
      byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
      System.out.printf("Ciphertext: %s%n", ciphertext);
    }
  }

  // Converts a base64-encoded PEM certificate like the one returned from Cloud
  // KMS into a DER formatted certificate for use with the Java APIs.
  private byte[] convertPemToDer(String pem) {
    BufferedReader bufferedReader = new BufferedReader(new StringReader(pem));
    String encoded =
        bufferedReader
            .lines()
            .filter(line -> !line.startsWith("-----BEGIN") && !line.startsWith("-----END"))
            .collect(Collectors.joining());
    return Base64.getDecoder().decode(encoded);
  }
}

Node.js

Pour exécuter ce code, commencez par configurer un environnement de développement Node.js, puis installez le SDK Cloud KMS pour Node.js.

//
// 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 versionId = '123';
// 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 version name
const versionName = client.cryptoKeyVersionPath(
  projectId,
  locationId,
  keyRingId,
  keyId,
  versionId
);

async function encryptAsymmetric() {
  // Get public key from Cloud KMS
  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');
  }

  // Import and setup crypto
  const crypto = require('crypto');

  // Encrypt plaintext locally using the public key. This example uses a key
  // that was configured with sha256 hash with OAEP padding. Update these
  // values to match the Cloud KMS key.
  //
  // NOTE: In Node < 12, this function does not properly consume the OAEP
  // padding and thus produces invalid ciphertext. If you are using Node to do
  // public key encryption, please use version 12+.
  const ciphertextBuffer = crypto.publicEncrypt(
    {
      key: publicKey.pem,
      oaepHash: 'sha256',
      padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
    },
    plaintextBuffer
  );

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

return encryptAsymmetric();

PHP

Pour exécuter ce code, commencez par en apprendre plus sur l'utilisation de PHP sur Google Cloud, puis installez le SDK Cloud KMS pour PHP.

function encrypt_asymmetric(
    string $projectId = 'my-project',
    string $locationId = 'us-east1',
    string $keyRingId = 'my-key-ring',
    string $keyId = 'my-key',
    string $versionId = '123',
    string $plaintext = '...'
): void {
    // PHP has limited support for asymmetric encryption operations.
    // Specifically, openssl_public_encrypt() does not allow customizing
    // algorithms or padding. Thus, it is not currently possible to use PHP
    // core for asymmetric operations on RSA keys.
    //
    // Third party libraries like phpseclib may provide the required
    // functionality. Google does not endorse this external library.
}

Python

Pour exécuter ce code, commencez par configurer un environnement de développement Python, puis installez le SDK Cloud KMS pour Python.


# Import base64 for printing the ciphertext.
import base64

# Import cryptographic helpers from the cryptography package.
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding

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


def encrypt_asymmetric(
    project_id: str,
    location_id: str,
    key_ring_id: str,
    key_id: str,
    version_id: str,
    plaintext: str,
) -> bytes:
    """
    Encrypt plaintext using the public key portion of 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 version to use (e.g. '1').
        plaintext (string): message to encrypt

    Returns:
        bytes: Encrypted ciphertext.

    """

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

    # 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
    )

    # Get the public key.
    public_key = client.get_public_key(request={"name": key_version_name})

    # Extract and parse the public key as a PEM-encoded RSA key.
    pem = public_key.pem.encode("utf-8")
    rsa_key = serialization.load_pem_public_key(pem, default_backend())

    # Construct the padding. Note that the padding differs based on key choice.
    sha256 = hashes.SHA256()
    mgf = padding.MGF1(algorithm=sha256)
    pad = padding.OAEP(mgf=mgf, algorithm=sha256, label=None)

    # Encrypt the data using the public key.
    ciphertext = rsa_key.encrypt(plaintext_bytes, pad)
    print(f"Ciphertext: {base64.b64encode(ciphertext)!r}")
    return ciphertext

Ruby

Pour exécuter ce code, commencez par configurer un environnement de développement Ruby, puis installez le SDK Cloud KMS pour Ruby.

# Ruby has limited support for asymmetric encryption operations. Specifically,
# public_encrypt() does not allow customizing the MGF hash algorithm. Thus, it
# is not currently possible to use Ruby core for asymmetric encryption
# operations on RSA keys from Cloud KMS.
#
# Third party libraries may provide the required functionality. Google does
# not endorse these external libraries.

Déchiffrer des données

Utilisez Cloud KMS pour réaliser le déchiffrement.

gcloud

Pour utiliser Cloud KMS sur la ligne de commande, commencez par installer ou mettre à jour la dernière version de Google Cloud CLI.

gcloud kms asymmetric-decrypt \
    --version key-version \
    --key key \
    --keyring key-ring \
    --location location  \
    --ciphertext-file file-path-with-encrypted-data \
    --plaintext-file file-path-to-store-plaintext

Remplacez key-version par la version de clé, ou omettez l'option --version pour détecter automatiquement la version. Remplacez key par le nom de la clé à utiliser pour le déchiffrement. Remplacez key-ring par le nom du trousseau de clés où sera située la clé. Remplacez location par l'emplacement Cloud KMS du trousseau de clés. Remplacez file-path-with-encrypted-data et file-path-to-store-plaintext par les chemins d'accès aux fichiers locaux pour la lecture des données chiffrées et l'enregistrement du résultat déchiffré.

Pour en savoir plus sur toutes les options et valeurs possibles, exécutez la commande avec l'option --help.

Pour afficher le contenu du fichier déchiffré, ouvrez-le dans votre éditeur ou votre terminal. Voici un exemple qui montre le contenu du fichier à l'aide de la commande cat :

cat ./my-file.txt

C#

Pour exécuter ce code, commencez par configurer un environnement de développement C#, puis installez le SDK Cloud KMS pour C#.


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

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

        // Build the key version name.
        CryptoKeyVersionName keyVersionName = new CryptoKeyVersionName(projectId, locationId, keyRingId, keyId, keyVersionId);

        // Call the API.
        AsymmetricDecryptResponse result = client.AsymmetricDecrypt(keyVersionName, 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

Pour exécuter ce code, commencez par configurer un environnement de développement Go, puis installez le SDK Cloud KMS pour Go.

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

// decryptAsymmetric will attempt to decrypt a given ciphertext with an
// 'RSA_DECRYPT_OAEP_2048_SHA256' key from Cloud KMS.
func decryptAsymmetric(w io.Writer, name string, ciphertext []byte) error {
	// name := "projects/my-project/locations/us-east1/keyRings/my-key-ring/cryptoKeys/my-key/cryptoKeyVersions/123"
	// ciphertext := []byte("...")  // result of an asymmetric 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.AsymmetricDecryptRequest{
		Name:             name,
		Ciphertext:       ciphertext,
		CiphertextCrc32C: wrapperspb.Int64(int64(ciphertextCRC32C)),
	}

	// Call the API.
	result, err := client.AsymmetricDecrypt(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 result.VerifiedCiphertextCrc32C == false {
		return fmt.Errorf("AsymmetricDecrypt: request corrupted in-transit")
	}
	if int64(crc32c(result.Plaintext)) != result.PlaintextCrc32C.Value {
		return fmt.Errorf("AsymmetricDecrypt: response corrupted in-transit")
	}

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

Java

Pour exécuter ce code, commencez par configurer un environnement de développement Java et installez le SDK Cloud KMS pour Java.

import com.google.cloud.kms.v1.AsymmetricDecryptResponse;
import com.google.cloud.kms.v1.CryptoKeyVersionName;
import com.google.cloud.kms.v1.KeyManagementServiceClient;
import com.google.protobuf.ByteString;
import java.io.IOException;

public class DecryptAsymmetric {

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

  // Decrypt data that was encrypted using the public key component of the given
  // key version.
  public void decryptAsymmetric(
      String projectId,
      String locationId,
      String keyRingId,
      String keyId,
      String keyVersionId,
      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, key,
      // and key version.
      CryptoKeyVersionName keyVersionName =
          CryptoKeyVersionName.of(projectId, locationId, keyRingId, keyId, keyVersionId);

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

Node.js

Pour exécuter ce code, commencez par configurer un environnement de développement Node.js, puis installez le SDK Cloud KMS pour Node.js.

//
// 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 versionId = '123';
// 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 version name
const versionName = client.cryptoKeyVersionPath(
  projectId,
  locationId,
  keyRingId,
  keyId,
  versionId
);

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

async function decryptAsymmetric() {
  const [decryptResponse] = await client.asymmetricDecrypt({
    name: versionName,
    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 (!decryptResponse.verifiedCiphertextCrc32c) {
    throw new Error('AsymmetricDecrypt: request corrupted in-transit');
  }
  if (
    crc32c.calculate(decryptResponse.plaintext) !==
    Number(decryptResponse.plaintextCrc32c.value)
  ) {
    throw new Error('AsymmetricDecrypt: response corrupted in-transit');
  }

  // NOTE: The ciphertext must be properly formatted. In Node < 12, the
  // crypto.publicEncrypt() function does not properly consume the OAEP
  // padding and thus produces invalid ciphertext. If you are using Node to do
  // public key encryption, please use version 12+.
  const plaintext = decryptResponse.plaintext.toString('utf8');

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

return decryptAsymmetric();

PHP

Pour exécuter ce code, commencez par en apprendre plus sur l'utilisation de PHP sur Google Cloud, puis installez le SDK Cloud KMS pour PHP.

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

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

    // Build the key version name.
    $keyVersionName = $client->cryptoKeyVersionName($projectId, $locationId, $keyRingId, $keyId, $versionId);

    // Call the API.
    $asymmetricDecryptRequest = (new AsymmetricDecryptRequest())
        ->setName($keyVersionName)
        ->setCiphertext($ciphertext);
    $decryptResponse = $client->asymmetricDecrypt($asymmetricDecryptRequest);
    printf('Plaintext: %s' . PHP_EOL, $decryptResponse->getPlaintext());

    return $decryptResponse;
}

Python

Pour exécuter ce code, commencez par configurer un environnement de développement Python, puis installez le SDK Cloud KMS pour Python.

from google.cloud import kms


def decrypt_asymmetric(
    project_id: str,
    location_id: str,
    key_ring_id: str,
    key_id: str,
    version_id: str,
    ciphertext: bytes,
) -> kms.DecryptResponse:
    """
    Decrypt the ciphertext using 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 version to use (e.g. '1').
        ciphertext (bytes): Encrypted bytes to decrypt.

    Returns:
        DecryptResponse: Response including plaintext.

    """

    # 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
    )

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

    # Call the API.
    decrypt_response = client.asymmetric_decrypt(
        request={
            "name": key_version_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.verified_ciphertext_crc32c:
        raise Exception("The request sent to the server was corrupted in-transit.")
    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

Pour exécuter ce code, commencez par configurer un environnement de développement Ruby, puis installez le SDK Cloud KMS pour Ruby.

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

# 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.
response = client.asymmetric_decrypt key_version_name, ciphertext
puts "Plaintext: #{response.plaintext}"

API

Ces exemples utilisent curl comme client HTTP pour démontrer l'utilisation de l'API. Pour en savoir plus sur le contrôle des accès, consultez la page Accéder à l'API Cloud KMS.

Utilisez la méthode CryptoKeyVersions.asymmetricDecrypt.

Dépannage

incorrect key purpose: ASYMMETRIC_SIGN

Vous pouvez uniquement déchiffrer des données avec une clé dotée de l'objectif ASYMMETRIC_DECRYPT.

invalid parameter lors du déchiffrement sur macOS

La version d'OpenSSL installée sur macOS n'est pas compatible avec les options utilisées pour déchiffrer les données dans cette rubrique. Pour suivre ces étapes sur macOS, installez OpenSSL à partir de Homebrew.

data too large for key size

La taille maximale de la charge utile pour le déchiffrement RSA dépend de la taille de la clé et de l'algorithme de remplissage. Tous les formats de chiffrement RSA utilisés par Cloud KMS utilisent le remplissage OAEP, standardisé dans RFC 2437. À titre de référence, les algorithmes ci-dessous acceptent les tailles maximales de charge utile suivantes (maxMLen, en octets):

Algorithm Paramètres Longueur maximum du message
RSA_DECRYPT_OAEP_2048_SHA256 k = 256 ; hLen = 32 ; maxMLen = 190
RSA_DECRYPT_OAEP_3072_SHA256 k = 384 ; hLen = 32 ; maxMLen = 318
RSA_DECRYPT_OAEP_4096_SHA256 k = 512 ; hLen = 32 ; maxMLen = 446
RSA_DECRYPT_OAEP_4096_SHA512 k = 512 ; hLen = 64 ; maxMLen = 382

Le chiffrement asymétrique n'est pas recommandé pour les messages de longueur variable qui peuvent être supérieurs à ces limites. Préférez plutôt un chiffrement hybride. Tink est une bibliothèque de cryptographie qui utilise cette approche.