Encripta y desencripta datos con una clave asimétrica

En este tema se describe cómo crear y usar una clave para la encriptación asimétrica con una clave de RSA. Consulta Crear y validar firmas digitales, si deseas usar claves asimétricas para crear y validar firmas. Además, consulta Encriptación y desencriptación de datos si quieres usar claves asimétricas para estas operaciones.

En la encriptación asimétrica, se usa la porción de clave pública de la clave asimétrica, mientras que en la desencriptación se usa la porción de clave privada. Cloud KMS ofrece la función de recuperar la clave pública, además de desencriptar el cifrado que se encriptó con esta. Cloud KMS no permite el acceso directo a la clave privada.

Antes de comenzar

Control de acceso a la clave

  • Para un usuario o servicio que recuperará la clave pública, otorga el permiso cloudkms.cryptoKeyVersions.viewPublicKey en la clave asimétrica. Se necesita la clave pública para encriptar los datos.

  • Para un usuario o servicio que desencriptará datos que se encriptaron con la clave pública, otorga el permiso cloudkms.cryptoKeyVersions.useToDecrypt en la clave asimétrica.

Para conocer más sobre los permisos y funciones en Cloud KMS, sigue este vínculo.

Encriptar datos

Si no tienes la clave pública, recupérala.

Línea de comandos

En este ejemplo, se supone que la clave pública se encuentra en un archivo llamado rsa-decrypt-key.pub.

  1. Haz clic en el botón Activar Cloud Shell en la parte superior de la ventana de la consola. Activar Cloud Shell Se abrirá una sesión de Cloud Shell en un marco nuevo en la parte inferior de la consola, que mostrará una ventana emergente con una línea de comandos. La sesión del shell puede tardar unos segundos en inicializarse. Sesión de Cloud Shell

  2. Crea un archivo de texto sin formato en la ventana emergente de la línea de comandos de Cloud Shell.

    echo "my secret message" > ~/my-secret-file
    
  3. Encripta el archivo con OpenSSL. En el ejemplo, se usa el resumen SHA-256. Actualmente todos los algoritmos de encriptación asimétrica usan este resumen.

    openssl pkeyutl -in ~/my-secret-file \
      -encrypt -pubin \
      -inkey ~/rsa-decrypt-key.pub \
      -pkeyopt rsa_padding_mode:oaep \
      -pkeyopt rsa_oaep_md:sha256 \
      -pkeyopt rsa_mgf1_md:sha256 > ~/my-secret-file.enc
    

Go

func encryptRSA(ctx context.Context, client *cloudkms.Service, keyPath string, plaintext []byte) ([]byte, error) {
	abstractKey, err := getAsymmetricPublicKey(ctx, client, keyPath)
	if err != nil {
		return nil, err
	}

	// Perform type assertion to get the RSA key.
	rsaKey := abstractKey.(*rsa.PublicKey)

	ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, rsaKey, plaintext, nil)
	if err != nil {
		return nil, fmt.Errorf("encryption failed: %+v", err)
	}
	return ciphertext, nil
}

Java

/**
 * Encrypt data locally using an 'RSA_DECRYPT_OAEP_2048_SHA256' public key
 * retrieved from Cloud KMS
 *
 * Requires:
 *   java.security.PublicKey
 *   java.security.Security
 *   javax.crypto.Cipher
 *   org.bouncycastle.jce.provider.BouncyCastleProvider
 */
public static byte[] encryptRSA(byte[] plaintext, CloudKMS client, String keyPath)
    throws IOException, IllegalBlockSizeException, NoSuchPaddingException,
           InvalidKeySpecException, NoSuchProviderException, BadPaddingException,
           NoSuchAlgorithmException, InvalidKeyException {
  Security.addProvider(new BouncyCastleProvider());
  PublicKey rsaKey = getAsymmetricPublicKey(client, keyPath);

  Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPWITHSHA256ANDMGF1PADDING", "BC");
  cipher.init(Cipher.ENCRYPT_MODE, rsaKey);
  return cipher.doFinal(plaintext);
}

Python

def encryptRSA(plaintext, client, key_path):
    """
    Encrypt the input plaintext (bytes) locally using an
    'RSA_DECRYPT_OAEP_2048_SHA256' public key retrieved from Cloud KMS

    Requires:
      cryptography.hazmat.primitives.asymmetric.padding
      cryptography.hazmat.primitives.hashes
    """
    public_key = getAsymmetricPublicKey(client, key_path)
    pad = padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),
                       algorithm=hashes.SHA256(),
                       label=None)
    return public_key.encrypt(plaintext, pad)

Desencriptar datos

Desencripta los datos con Cloud KMS.

Línea de comandos

gcloud alpha kms asymmetric-decrypt \
  --location [LOCATION] \
  --keyring [KEYRING_NAME] \
  --key [KEY_NAME] \
  --version [KEY_VERSION] \
  --ciphertext-file ~/my-secret-file.enc \
  --plaintext-file ~/my-secret-file.dec \

Permite mostrar el contenido del archivo desencriptado.

cat ~/my-secret-file.dec

Debes ver el mismo texto que creaste para tu archivo de texto sin formato.

my secret message

API

Usa el método CryptoKeyVersions.asymmetricDecrypt.

  • Configura el valor de ciphertext de la solicitud en función del cifrado que se creó cuando encriptaste el texto sin formato.

La respuesta CryptoKeyVersions.asymmetricDecrypt contiene los datos desencriptados.

Go

func decryptRSA(ctx context.Context, client *cloudkms.Service, keyPath string, ciphertext []byte) ([]byte, error) {
	decryptRequest := &cloudkms.AsymmetricDecryptRequest{
		Ciphertext: base64.StdEncoding.EncodeToString(ciphertext),
	}
	response, err := client.Projects.Locations.KeyRings.CryptoKeys.CryptoKeyVersions.
		AsymmetricDecrypt(keyPath, decryptRequest).Context(ctx).Do()
	if err != nil {
		return nil, fmt.Errorf("decryption request failed: %+v", err)
	}
	plaintext, err := base64.StdEncoding.DecodeString(response.Plaintext)
	if err != nil {
		return nil, fmt.Errorf("failed to decode decryted string: %+v", err)

	}
	return plaintext, nil
}

Java

/**
 * Decrypt a given ciphertext using an 'RSA_DECRYPT_OAEP_2048_SHA256' private key
 * stored on Cloud KMS
 */
public static byte[] decryptRSA(byte[] ciphertext, CloudKMS client, String keyPath)
    throws IOException {
  AsymmetricDecryptRequest request = new AsymmetricDecryptRequest().encodeCiphertext(ciphertext);
  AsymmetricDecryptResponse response = client.projects()
                                             .locations()
                                             .keyRings()
                                             .cryptoKeys()
                                             .cryptoKeyVersions()
                                             .asymmetricDecrypt(keyPath, request)
                                             .execute();
  return response.decodePlaintext();
}

Python

def decryptRSA(ciphertext, client, key_path):
    """
    Decrypt the input ciphertext (bytes) using an
    'RSA_DECRYPT_OAEP_2048_SHA256' private key stored on Cloud KMS

    Requires:
      base64
    """
    request_body = {'ciphertext': base64.b64encode(ciphertext).decode('utf-8')}
    request = client.projects() \
                    .locations() \
                    .keyRings() \
                    .cryptoKeys() \
                    .cryptoKeyVersions() \
                    .asymmetricDecrypt(name=key_path,
                                       body=request_body)
    response = request.execute()
    plaintext = base64.b64decode(response['plaintext'])
    return plaintext

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Documentación de Cloud KMS