Como criptografar e descriptografar dados com uma chave simétrica

Neste tópico, você aprende o que fazer com as seguintes operações de chave simétrica:

  • Criptografar texto ou conteúdo binário (texto simples) usando uma chave do Cloud KMS.
  • Descriptografar texto cifrado que foi criptografado com uma chave do Cloud KMS.

Se você quiser usar uma chave assimétrica para criptografia, consulte Como criptografar e descriptografar dados com uma chave assimétrica.

Antes de começar

  1. Crie um keyring e uma chave, conforme descrito em Como criar keyrings e chaves.

  2. Verifique se o usuário que está chamando os métodos de criptografia e descriptografia tem as permissões cloudkms.cryptoKeyVersions.useToEncrypt e cloudkms.cryptoKeyVersions.useToDecrypt na chave usada para criptografar ou descriptografar.

    Uma maneira de permitir que um usuário criptografe ou descriptografe é adicionar o usuário aos papéis de IAM roles/cloudkms.cryptoKeyEncrypter, roles/cloudkms.cryptoKeyDecrypter ou roles/cloudkms.cryptoKeyEncrypterDecrypter dessa chave. Para mais informações, consulte Permissões e papéis.

  3. Opcional: se você for usar a biblioteca de cliente para o Cloud KMS, instale-a no idioma de sua preferência.

  4. Opcional: se você for usar a ferramenta de linha de comando gcloud, instale o SDK do Cloud.

Criptografar

Linha de comando

Para criptografar dados, forneça as informações de chave apropriadas, especifique o nome do arquivo de texto simples a ser criptografado e o nome do arquivo com o conteúdo criptografado.

gcloud kms encrypt \
  --location=[LOCATION]  \
  --keyring=[KEY_RING] \
  --key=[KEY] \
  --plaintext-file=[FILEPATH_AND_FILENAME_TO_ENCRYPT] \
  --ciphertext-file=[FILEPATH_AND_FILENAME].enc

Por exemplo, se text.txt for o nome do arquivo de texto simples a ser criptografado:

gcloud kms encrypt \
  --location global \
  --keyring my_keyring \
  --key my_key \
  --plaintext-file text.txt \
  --ciphertext-file text.enc

O arquivo de texto simples não pode ultrapassar 64 KiB.

O comando encrypt é compatível com uma sinalização --additional-authenticated-data- file opcional para especificar um arquivo que contenha dados autenticados adicionais. O arquivo de dados autenticados adicionais não pode ultrapassar 64 KiB.

Se --plaintext-file ou --additional-authenticated-data-file estiver definido como -, esse arquivo será lido de stdin. Da mesma maneira, se --ciphertext-file estiver definido como -, o texto criptografado será gravado em stdout. Ao usar a entrada padrão, observe que quaisquer caracteres de espaço em branco fornecidos (por exemplo, novas linhas produzidas por echo ou outros comandos de shell) serão incluídos no texto criptografado.

O comando encrypt é compatível com uma sinalização --version opcional para indicar a versão da chave a ser usada para criptografia. Por padrão, é usada a versão principal.

Os exemplos de encrypt a seguir mostram como especificar uma chave de versão e dados autenticados adicionais.

gcloud kms encrypt \
  --location=[LOCATION]  \
  --keyring=[KEY_RING] \
  --key=[KEY] \
  --version=[KEY_VERSION] \
  --additional-authenticated-data-file=[ADDITIONAL_AUTHENTICATED_DATA_FILEPATH_AND_FILENAME] \
  --plaintext-file=[FILEPATH_AND_FILENAME_TO_ENCRYPT] \
  --ciphertext-file=[FILEPATH_AND_FILENAME].enc

Protocolo

É preciso que o conteúdo a ser criptografado enviado para o Cloud KMS em JSON seja codificado em base64. Para informações sobre como codificar e decodificar usando base64, consulte Codificação em base64.

Para criptografar dados, faça uma solicitação POST e forneça as informações apropriadas do projeto e da chave. Além disso, especifique o texto codificado em base64 a ser criptografado no campo plaintext do corpo da solicitação. Substitua API_KEY por uma chave de API válida. Para informações sobre como gerar uma chave de API, consulte Como acessar a API.

POST https://cloudkms.googleapis.com/v1/projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[keyring_name]/cryptoKeys/[key_name]:encrypt&key=API_KEY
{
  "plaintext": "U3VwZXIgc2VjcmV0IHRleHQgdGhhdCBtdXN0IGJlIGVuY3J5cHRlZAo=",
}

Este é um exemplo que usa curl:

curl -s -X POST "https://cloudkms.googleapis.com/v1/projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING_NAME]/cryptoKeys/[KEY_NAME]:encrypt" \
  -d "{\"plaintext\":\"[BASE64_ENCODED_INPUT]\"}" \
  -H "Authorization:Bearer [API_KEY]"\
  -H "Content-Type:application/json"

C#

        public static void Encrypt(string projectId, string locationId, string keyRingId, string cryptoKeyId,
string plaintextFile, string ciphertextFile)
        {
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
            CryptoKeyName cryptoKeyName =
                new CryptoKeyName(projectId, locationId, keyRingId, cryptoKeyId);

            byte[] plaintext = File.ReadAllBytes(plaintextFile);
            CryptoKeyPathName pathName = CryptoKeyPathName.Parse(cryptoKeyName.ToString());
            EncryptResponse result = client.Encrypt(pathName, ByteString.CopyFrom(plaintext));

            // Output encrypted data to a file.
            File.WriteAllBytes(ciphertextFile, result.Ciphertext.ToByteArray());
            Console.Write($"Encrypted file created: {ciphertextFile}");
        }

Go

import (
	"context"
	"fmt"

	cloudkms "cloud.google.com/go/kms/apiv1"
	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)

// encryptSymmetric will encrypt the input plaintext with the specified symmetric key.
func encryptSymmetric(name string, plaintext []byte) ([]byte, error) {
	// name := "projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys/KEY_ID"
	// plaintext := []byte("Sample message")
	ctx := context.Background()
	client, err := cloudkms.NewKeyManagementClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("cloudkms.NewKeyManagementClient: %v", err)
	}

	// Build the request.
	req := &kmspb.EncryptRequest{
		Name:      name,
		Plaintext: plaintext,
	}
	// Call the API.
	resp, err := client.Encrypt(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("Encrypt: %v", err)
	}
	return resp.Ciphertext, nil
}

Java


/**
 * Encrypts the given plaintext using the specified crypto key.
 */
public static byte[] encrypt(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, byte[] plaintext)
    throws IOException {

  // Create the KeyManagementServiceClient using try-with-resources to manage client cleanup.
  try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {

    // The resource name of the cryptoKey
    String resourceName = CryptoKeyName.format(projectId, locationId, keyRingId, cryptoKeyId);

    // Encrypt the plaintext with Cloud KMS.
    EncryptResponse response = client.encrypt(resourceName, ByteString.copyFrom(plaintext));

    // Extract the ciphertext from the response.
    return response.getCiphertext().toByteArray();
  }
}

Node.js

async function encrypt(
  projectId = 'your-project-id', // Your GCP projectId
  keyRingId = 'my-key-ring', // Name of the crypto key's key ring
  cryptoKeyId = 'my-key', // Name of the crypto key, e.g. "my-key"
  plaintextFileName = './path/to/plaintext.txt',
  ciphertextFileName = './path/to/plaintext.txt.encrypted'
) {
  const fs = require('fs');
  const {promisify} = require('util');

  // Import the library and create a client
  const kms = require('@google-cloud/kms');
  const client = new kms.KeyManagementServiceClient();

  // The location of the crypto key's key ring, e.g. "global"
  const locationId = 'global';

  // Reads the file to be encrypted
  const readFile = promisify(fs.readFile);
  const contentsBuffer = await readFile(plaintextFileName);
  const plaintext = contentsBuffer.toString('base64');
  const name = client.cryptoKeyPath(
    projectId,
    locationId,
    keyRingId,
    cryptoKeyId
  );

  // Encrypts the file using the specified crypto key
  const [result] = await client.encrypt({name, plaintext});
  const writeFile = promisify(fs.writeFile);
  await writeFile(ciphertextFileName, Buffer.from(result.ciphertext, 'base64'));
  console.log(`Encrypted ${plaintextFileName} using ${result.name}.`);
  console.log(`Result saved to ${ciphertextFileName}.`);
}

PHP

use Google\Cloud\Kms\V1\KeyManagementServiceClient;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The location ID of the crypto key. Can be "global", "us-west1", etc.';
// $keyRingId = 'The KMS key ring ID';
// $cryptoKeyId = 'The KMS key ID';
// $plaintextFileName = 'The path to the file containing plaintext to encrypt';
// $ciphertextFileName = 'The path to write the ciphertext';

$kms = new KeyManagementServiceClient();

// The resource name of the CryptoKey.
$cryptoKeyName = $kms->cryptoKeyName($projectId, $locationId, $keyRingId, $cryptoKeyId);

$plaintext = file_get_contents($plaintextFileName);
$response = $kms->encrypt($cryptoKeyName, $plaintext);

// Write the encrypted text to a file.
file_put_contents($ciphertextFileName, $response->getCiphertext());
printf('Saved encrypted text to %s' . PHP_EOL, $ciphertextFileName);

Python

def encrypt_symmetric(project_id, location_id, key_ring_id, crypto_key_id,
                      plaintext):
    """Encrypts input plaintext data using the provided symmetric CryptoKey."""

    from google.cloud import kms_v1

    # Creates an API client for the KMS API.
    client = kms_v1.KeyManagementServiceClient()

    # The resource name of the CryptoKey.
    name = client.crypto_key_path_path(project_id, location_id, key_ring_id,
                                       crypto_key_id)

    # Use the KMS API to encrypt the data.
    response = client.encrypt(name, plaintext)
    return response.ciphertext

Ruby

# project_id      = "Your Google Cloud project ID"
# location_id     = "The location of the key ring"
# key_ring_id     = "The ID of the key ring"
# crypto_key_id   = "The ID of the crypto key"
# plaintext_file  = "File to encrypt"
# ciphertext_file = "File to store encrypted input data"

require "google/cloud/kms/v1"
CloudKMS = Google::Cloud::Kms::V1

# Initialize the client
client = CloudKMS::KeyManagementServiceClient.new

# The crypto key to use
crypto_key = CloudKMS::KeyManagementServiceClient.crypto_key_path(
  project_id, location_id, key_ring_id, crypto_key_id
)

# Read the secret data from the file
plaintext = File.open(plaintext_file, "rb", &:read)

# Use the KMS API to encrypt the data
response = client.encrypt crypto_key, plaintext

# Write the encrypted binary data to the output file
File.open(ciphertext_file, "wb") { |f| f.write response.ciphertext }

puts "Saved encrypted #{plaintext_file} as #{ciphertext_file}"

Descriptografar

Linha de comando

Para descriptografar dados, forneça as informações de chave apropriadas, especifique o nome do arquivo a ser descriptografado e especifique o nome do arquivo com o conteúdo descriptografado.

gcloud kms decrypt \
  --location=[LOCATION] \
  --keyring=[KEY_RING] \
  --key=[KEY] \
  --ciphertext-file=[FILEPATH_AND_FILENAME_TO_DECRYPT] \
  --plaintext-file=[FILEPATH_AND_FILENAME_TO_DECRYPT].dec

Por exemplo, se text.enc for o nome do arquivo de texto criptografado a descriptografar:

gcloud kms decrypt \
  --location=global \
  --keyring=my_keyring \
  --key=my_key \
  --ciphertext-file=text.enc \
  --plaintext-file=text.dec

O comando decrypt é compatível com uma sinalização --additional-authenticated-data- file opcional para especificar um arquivo que contenha dados autenticados adicionais. O arquivo de dados autenticados adicionais não pode ultrapassar 64 KiB.

Se --ciphertext-file ou --additional-authenticated-data-file estiver definido como -, esse arquivo será lido de stdin. Da mesma forma, se --plaintext-file estiver definido como -, o texto simples descriptografado será gravado em stdout. Ao usar a entrada padrão, observe que quaisquer caracteres de espaço em branco fornecidos (por exemplo, novas linhas produzidas por echo ou outros comandos de shell) serão incluídos na tentativa de descriptografia.

Os exemplos de decrypt a seguir mostram como especificar dados autenticados adicionais.

gcloud kms decrypt \
  --location=[LOCATION] \
  --keyring=[KEY_RING] \
  --key=[KEY] \
  --additional-authenticated-data-file=[ADDITIONAL_AUTHENTICATED_DATA_FILEPATH_AND_FILENAME] \
  --ciphertext-file=[FILEPATH_AND_FILENAME_TO_DECRYPT] \
  --plaintext-file=[FILEPATH_AND_FILENAME_TO_DECRYPT].dec

Protocolo

O texto descriptografado retornado no JSON a partir do Cloud KMS é codificado em base64. Para informações sobre como codificar e decodificar usando base64, consulte Codificação em base64.

Para descriptografar dados criptografados, crie uma solicitação POST e forneça as informações apropriadas do projeto e da chave. Além disso, especifique o texto criptografado a ser descriptografado no campo ciphertext da solicitação. Substitua API_KEY por uma chave de API válida. Para informações sobre como gerar uma chave de API, consulte Como acessar a API.

POST https://cloudkms.googleapis.com/v1/projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING_NAME]/cryptoKeys/[KEY_NAME]:decrypt&key=API_KEY
{
  "ciphertext": "CiQAhMwwBo61cHas7dDgifrUFs5zNzBJ2uZtVFq4ZPEl6fUVT4kSmQ...",
}

Este é um exemplo que usa curl:

curl -s -X POST "https://cloudkms.googleapis.com/v1/projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEYRING_NAME]/cryptoKeys/[KEY_NAME]:decrypt" \
  -d "{\"ciphertext\":\"[ENCRYPTED_CONTENT]\"}" \
  -H "Authorization:Bearer [API_KEY]"\
  -H "Content-Type:application/json"

C#

        public static void Decrypt(string projectId, string locationId, string keyRingId, string cryptoKeyId,
    string ciphertextFile, string plaintextFile)
        {
            KeyManagementServiceClient client = KeyManagementServiceClient.Create();
            CryptoKeyName cryptoKeyName =
                new CryptoKeyName(projectId, locationId, keyRingId, cryptoKeyId);

            byte[] ciphertext = File.ReadAllBytes(ciphertextFile);
            DecryptResponse result = client.Decrypt(cryptoKeyName, ByteString.CopyFrom(ciphertext));

            // Output decrypted data to a file.
            File.WriteAllBytes(plaintextFile, result.Plaintext.ToByteArray());
            Console.Write($"Decrypted file created: {plaintextFile}");
        }

Go

import (
	"context"
	"fmt"

	cloudkms "cloud.google.com/go/kms/apiv1"
	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)

// decryptSymmetric will decrypt the input ciphertext bytes using the specified symmetric key.
func decryptSymmetric(name string, ciphertext []byte) ([]byte, error) {
	// name := "projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys/KEY_ID"
	// cipherBytes, err := encryptRSA(rsaDecryptPath, []byte("Sample message"))
	// if err != nil {
	//   return nil, fmt.Errorf("encryptRSA: %v", err)
	// }
	// ciphertext := base64.StdEncoding.EncodeToString(cipherBytes)
	ctx := context.Background()
	client, err := cloudkms.NewKeyManagementClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("cloudkms.NewKeyManagementClient: %v", err)
	}

	// Build the request.
	req := &kmspb.DecryptRequest{
		Name:       name,
		Ciphertext: ciphertext,
	}
	// Call the API.
	resp, err := client.Decrypt(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("Decrypt: %v", err)
	}
	return resp.Plaintext, nil
}

Java


/**
 * Decrypts the provided ciphertext with the specified crypto key.
 */
public static byte[] decrypt(
    String projectId, String locationId, String keyRingId, String cryptoKeyId, byte[] ciphertext)
    throws IOException {

  // Create the KeyManagementServiceClient using try-with-resources to manage client cleanup.
  try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {

    // The resource name of the cryptoKey
    String resourceName = CryptoKeyName.format(projectId, locationId, keyRingId, cryptoKeyId);

    // Decrypt the ciphertext with Cloud KMS.
    DecryptResponse response = client.decrypt(resourceName, ByteString.copyFrom(ciphertext));

    // Extract the plaintext from the response.
    return response.getPlaintext().toByteArray();
  }
}

Node.js

async function decrypt(
  projectId = 'your-project-id', // Your GCP projectId
  keyRingId = 'my-key-ring', // Name of the crypto key's key ring
  cryptoKeyId = 'my-key', // Name of the crypto key, e.g. "my-key"
  ciphertextFileName = './path/to/plaintext.txt.encrypted',
  plaintextFileName = './path/to/plaintext.txt.decrypted'
) {
  const fs = require('fs');
  const {promisify} = require('util');

  // Import the library and create a client
  const kms = require('@google-cloud/kms');
  const client = new kms.KeyManagementServiceClient();

  // The location of the crypto key's key ring, e.g. "global"
  const locationId = 'global';

  // Reads the file to be decrypted
  const readFile = promisify(fs.readFile);
  const contentsBuffer = await readFile(ciphertextFileName);
  const name = client.cryptoKeyPath(
    projectId,
    locationId,
    keyRingId,
    cryptoKeyId
  );
  const ciphertext = contentsBuffer.toString('base64');

  // Decrypts the file using the specified crypto key
  const [result] = await client.decrypt({name, ciphertext});

  // Writes the decrypted file to disk
  const writeFile = promisify(fs.writeFile);
  await writeFile(plaintextFileName, Buffer.from(result.plaintext, 'base64'));
  console.log(
    `Decrypted ${ciphertextFileName}, result saved to ${plaintextFileName}.`
  );
}

PHP

use Google\Cloud\Kms\V1\KeyManagementServiceClient;
use Google\Cloud\Kms\V1\CryptoKey;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The location ID of the crypto key. Can be "global", "us-west1", etc.';
// $keyRingId = 'The KMS key ring ID';
// $cryptoKeyId = 'The KMS key ID';
// $ciphertextFileName = 'The path to the file containing ciphertext to decrypt';
// $plaintextFileName = 'The path to write the plaintext';

$kms = new KeyManagementServiceClient();

// The resource name of the CryptoKey.
$cryptoKey = new CryptoKey();
$cryptoKeyName = $kms->cryptoKeyName($projectId, $locationId, $keyRingId, $cryptoKeyId);

$ciphertext = file_get_contents($ciphertextFileName);
$response = $kms->decrypt($cryptoKeyName, $ciphertext);

// Write the encrypted text to a file.
file_put_contents($plaintextFileName, $response->getPlaintext());
printf('Saved decrypted text to %s' . PHP_EOL, $plaintextFileName);

Python

def decrypt_symmetric(project_id, location_id, key_ring_id, crypto_key_id,
                      ciphertext):
    """Decrypts input ciphertext using the provided symmetric CryptoKey."""

    from google.cloud import kms_v1

    # Creates an API client for the KMS API.
    client = kms_v1.KeyManagementServiceClient()

    # The resource name of the CryptoKey.
    name = client.crypto_key_path_path(project_id, location_id, key_ring_id,
                                       crypto_key_id)
    # Use the KMS API to decrypt the data.
    response = client.decrypt(name, ciphertext)
    return response.plaintext

Ruby

# project_id    = "Your Google Cloud project ID"
# location_id   = "The location of the key ring"
# key_ring_id   = "The ID of the key ring"
# crypto_key_id = "The ID of the crypto key"
# ciphertext_file = "File to decrypt"
# plaintext_file  = "File to store decrypted data"

require "google/cloud/kms/v1"
CloudKMS = Google::Cloud::Kms::V1

# Initialize the client
client = CloudKMS::KeyManagementServiceClient.new

# The crypto key to use
crypto_key = CloudKMS::KeyManagementServiceClient.crypto_key_path(
  project_id, location_id, key_ring_id, crypto_key_id
)

# Read the encrypted data from the file
ciphertext = File.open(ciphertext_file, "rb", &:read)

# Use the KMS API to decrypt the data
response = client.decrypt crypto_key, ciphertext

# Write the decrypted text to the output file
File.open(plaintext_file, "wb") { |f| f.write response.plaintext }

puts "Saved decrypted #{ciphertext_file} as #{plaintext_file}"

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Cloud KMS