Cifrado de cliente para blobs

La biblioteca cliente de Azure Blob Storage para .NET permite tanto el cifrado de datos dentro de las aplicaciones de cliente antes de cargarlos en Azure Storage, como el descifrado de datos mientras estos se descargan al cliente. Asimismo, la biblioteca también admite la integración con Azure Key Vault para la administración de claves de la cuenta de almacenamiento.

Importante

Blob Storage admite el cifrado del servicio y de cliente. En la mayoría de los escenarios, Microsoft recomienda usar características de cifrado del servicio para facilitar su uso en la protección de los datos. Para aprender más sobre el cifrado del servicio, consulte Cifrado de Azure Storage para datos en reposo.

Para ver un tutorial paso a paso que le guíe por el proceso de cifrado de blobs mediante el cifrado de cliente y Azure Key Vault, consulte Cifrado y descifrado de blobs en Microsoft Azure Storage con Azure Key Vault.

Acerca del cifrado de cliente

La biblioteca cliente de Azure Blob Storage usa AES para cifrar los datos del usuario. Hay dos versiones del cifrado de cliente disponibles en la biblioteca cliente:

Advertencia

El uso de la versión 1 del cifrado de cliente ya no se recomienda debido a una vulnerabilidad de seguridad en la implementación de la biblioteca cliente del modo CBC. Para más información sobre esta vulnerabilidad de seguridad, consulte Actualización de Azure Storage del cifrado del lado cliente en el SDK para abordar la vulnerabilidad de seguridad. Si actualmente usa la versión 1, se recomienda actualizar la aplicación para usar la versión 2 y migrar los datos. A continuación, consulte la sección sobre cómo mitigar la vulnerabilidad de seguridad en las aplicaciones para obtener instrucciones adicionales.

Mitigación de la vulnerabilidad de seguridad en las aplicaciones

Debido a una vulnerabilidad de seguridad detectada en la implementación de la biblioteca cliente de Blob Storage del modo CBC, Microsoft recomienda realizar una o varias de las siguientes acciones inmediatamente:

  • Considere la posibilidad de usar características de cifrado del servicio en lugar del cifrado de cliente. Para más información sobre las características de cifrado del servicio, consulte Cifrado de Azure Storage para datos en reposo.

  • Si necesita usar el cifrado de cliente, migre las aplicaciones de la versión 1 del cifrado de cliente a la versión 2 del cifrado de cliente.

En la tabla siguiente se resumen los pasos que deberá seguir si decide migrar las aplicaciones a la versión 2 del cifrado de cliente:

Estado de cifrado de cliente Acciones recomendadas
La aplicación usa el cifrado de cliente con una versión de la biblioteca cliente que solo admite la versión 1 del cifrado de cliente. Actualice la aplicación para que use una versión de la biblioteca cliente que admita la versión 2 del cifrado de cliente. Consulte la sección sobre la matriz de compatibilidad del SDK para el cifrado de cliente para obtener una lista de las versiones admitidas. Más información...

Actualice el código para usar la versión 2 del cifrado de cliente. Más información...

Descargue los datos cifrados para descifrarlos y, a continuación, vuelva a cifrarlos con la versión 2 del cifrado de cliente. Más información...
La aplicación usa el cifrado de cliente con una versión de la biblioteca cliente que admite la versión 2 del cifrado de cliente. Actualice el código para usar la versión 2 del cifrado de cliente. Más información...

Descargue los datos cifrados para descifrarlos y, a continuación, vuelva a cifrarlos con la versión 2 del cifrado de cliente. Más información...

Además, Microsoft recomienda seguir los pasos siguientes para ayudar a proteger los datos:

  • Configure las cuentas de almacenamiento para usar puntos de conexión privados con el fin de proteger todo el tráfico entre la red virtual (VNet) y la cuenta de almacenamiento a través de un vínculo privado. Para obtener más información, consulte Uso de puntos de conexión privados para Azure Storage.
  • Limite el acceso a la red solo para redes específicas.

Matriz de compatibilidad del SDK para el cifrado de cliente

En la tabla siguiente se muestra qué versiones de las bibliotecas cliente para .NET, Java y Python admiten las diferentes versiones del cifrado de cliente:

.NET Java Python
Versiones 1 y 2 del cifrado de cliente Versiones 12.13.0 y posteriores Versiones 12.18.0 y posteriores Versiones 12.13.0 y posteriores
Solo la versión 1 del cifrado de cliente Versiones 12.12.0 y anteriores Versiones 12.17.0 y anteriores Versiones 12.12.0 y anteriores

Si la aplicación usa el cifrado de cliente con una versión anterior de la biblioteca cliente de .NET, Java o Python, primero debe actualizar el código a una versión que admita la versión 2 del cifrado de cliente. A continuación, debe descifrar y volver a cifrar los datos con la versión 2 del cifrado de cliente. Si es necesario, puede usar una versión de la biblioteca cliente que admita la versión 2 del cifrado de cliente en paralelo con una versión anterior de la biblioteca cliente mientras migra el código. Para ver ejemplos de código, consulte la sección sobre el ejemplo de cifrado y descifrado de un blob con la versión 2 del cifrado de cliente.

Funcionamiento del cifrado de cliente

Las bibliotecas cliente de Azure Blob Storage usan el cifrado de sobres para cifrar y descifrar los datos en el lado cliente. El cifrado de sobres cifra una clave con una o varias claves adicionales.

Las bibliotecas cliente de Blob Storage se basan en Azure Key Vault para proteger las claves que se usan para el cifrado de cliente. Para más información sobre Azure Key Vault, vea ¿Qué es Azure Key Vault?.

Cifrado y descifrado a través de la técnica de sobres

El cifrado funciona de la siguiente manera a través de la técnica de sobres:

  1. La biblioteca cliente de Azure Storage genera una clave de cifrado de contenido (CEK), que es una clave simétrica de un solo uso.

  2. Los datos de usuario se cifran mediante la CEK.

  3. Se encapsula la CEK (cifrada) con la clave de cifrado de clave (KEK). La KEK se identifica mediante un identificador de clave y puede ser un par de clave asimétrico o una clave simétrica. Puede administrar la KEK de forma local o almacenarla en una instancia de Azure Key Vault.

    La propia biblioteca cliente de Azure Storage no tiene nunca acceso a la KEK. La biblioteca invoca el algoritmo de encapsulado de clave proporcionado por Key Vault. Los usuarios pueden elegir utilizar proveedores personalizados para el ajuste y desajuste clave si lo desean.

  4. A continuación, se cargan los datos cifrados en Azure Blob Storage. La clave encapsulada junto con algunos metadatos de cifrado adicionales se almacena como metadatos en el blob.

El descifrado funciona de la siguiente manera a través de la técnica de sobres:

  1. La biblioteca cliente de Azure Storage asume que el usuario está administrando la KEK, ya sea localmente o en una instancia de Azure Key Vault. El usuario no necesita conocer la clave específica que se usó para el cifrado. En su lugar, se puede configurar y usar una resolución de clave que resuelva distintos identificadores de clave para las claves.
  2. La biblioteca cliente descarga los datos cifrados junto con cualquier material de cifrado que esté almacenado en Azure Storage.
  3. A continuación, la CEK encapsulada se desencapsula (descifra) mediante la KEK. La biblioteca cliente no tiene acceso a la KEK durante este proceso, sino que solo invoca el algoritmo de desencapsulado de Azure Key Vault u otro almacén de claves.
  4. La biblioteca cliente usa la CEK para descifrar los datos de usuario cifrados.

Cifrado y descifrado en la carga o descarga de blobs

La biblioteca cliente de Blob Storage solo admite el cifrado de blobs completos en la carga. En el caso de las descargas, se admiten tanto las descargas de intervalo como las completas.

Durante el cifrado, la biblioteca cliente genera un vector de inicialización (IV) aleatorio de 16 bytes y una CEK aleatoria de 32 bytes, y realiza el cifrado de sobres de los datos de blob con esta información. Posteriormente, la CEK encapsulada y algunos metadatos de cifrado adicionales se almacenan como metadatos de blob junto con el objeto blob cifrado.

Cuando un cliente descarga un blob completo, la CEK encapsulada se desencapsula y se utiliza junto con el vector de inicialización para devolver los datos descifrados al cliente.

Descargar un intervalo arbitrario en el blob cifrado implica ajustar el intervalo proporcionado por los usuarios para obtener una pequeña cantidad de datos adicionales que puedan usarse para descifrar correctamente el intervalo solicitado.

Todos los tipos de blobs (blobs en bloques, blobs de anexión) se pueden cifrar y descifrar usando este esquema.

Advertencia

Si está modificando o cargando sus propios metadatos para el blob, deberá asegurarse de que los metadatos de cifrado se conserven. Si carga nuevos metadatos sin conservar también los metadatos de cifrado, se perderán la CEK, el vector de inicialización y otros metadatos, y no podrá recuperar el contenido del blob. Al llamar a la operación Set Blob Metadata, siempre se reemplazan todos los metadatos de blob.

Al leer desde un blob cifrado o escribir en él, utilice comandos de carga completa del blob, como Put Blob, y comandos de descarga de blobs de intervalo o completos, como Get Blob. Evite escribir en un blob cifrado mediante operaciones de protocolo, como Colocar bloque, Colocar lista de bloque, Poner página o Anexar bloque. Llamar a estas operaciones en un blob cifrado puede dañarlo y hacer que no sea legible.

Ejemplo: Cifrado y descifrado de un blob con la versión 2 del cifrado de cliente

En el ejemplo de código de esta sección se muestra cómo usar la versión 2 del cifrado de cliente para cifrar y descifrar un blob.

Importante

Si tiene datos cifrados previamente con la versión 1 del cifrado de cliente, deberá descifrar esos datos y volver a cifrarlos con la versión 2 del cifrado de cliente. Consulte las instrucciones y el ejemplo de la biblioteca cliente a continuación.

Para usar el cifrado de cliente del código .NET, haga referencia a la biblioteca cliente de Blob Storage. Asegúrese de que usa la versión 12.13.0 o posterior. Si tiene que migrar de la versión 11.x a la versión 12.13.0, consulte la guía de migración.

Se requieren dos paquetes adicionales para la integración de Azure Key Vault para el cifrado de cliente:

  • El paquete Azure.Core proporciona las interfaces IKeyEncryptionKey y IKeyEncryptionKeyResolver. La biblioteca cliente de Blob Storage para .NET ya define este ensamblado como una dependencia.

  • El paquete Azure.Security.KeyVault.Keys (versión 4.x y posteriores) proporciona el cliente de REST de Key Vault y los clientes criptográficos que se usan con el cifrado de cliente. Deberá asegurarse de que se hace referencia a este paquete en el proyecto si usa Azure Key Vault como almacén de claves.

    Azure Key Vault está diseñado para claves maestras de gran valor. Por su parte, los valores de limitación por cada almacén de claves reflejan este diseño. A partir de la versión 4.1.0 de Azure.Security.KeyVault.Keys, la interfaz IKeyEncryptionKeyResolver no admite el almacenamiento en caché de claves. Si el almacenamiento en caché es necesario debido a una limitación, puede usar este enfoque mostrado en este ejemplo para insertar una capa de almacenamiento en caché en una instancia de Azure.Security.KeyVault.Keys.Cryptography.KeyResolver.

Los desarrolladores pueden proporcionar una clave, una resolución de clave, o bien una clave y una resolución de clave. Las claves se identifican con un identificador de claves que proporciona la lógica para la encapsulación y desencapsulación de la CEK. Una resolución de clave se utiliza para resolver una clave durante el proceso de descifrado. La resolución de clave define un método de resolución que devuelve una clave en función de un identificador de clave. La resolución ofrece a los usuarios la posibilidad de elegir entre varias claves que se administran en varias ubicaciones.

En el cifrado, se utiliza siempre la clave. Si no hay clave, se producirá un error.

En el descifrado, si se especifica la clave y su identificador coincide con el identificador de clave requerido, esa clave se usa para el descifrado. De lo contrario, la biblioteca cliente intenta llamar a la resolución. Si no se especifica ninguna resolución, la biblioteca cliente produce un error. Si se especifica una resolución, la resolución de clave se invoca para obtener la clave. Si se especifica la resolución, pero no se proporciona una asignación para el identificador de clave, la biblioteca cliente produce un error.

Para usar el cifrado de cliente, cree un objeto ClientSideEncryptionOptions y establézcalo en la creación de cliente con SpecializedBlobClientOptions. No se pueden establecer opciones de cifrado por API. Todo lo demás lo controlará la biblioteca de cliente internamente.

// Your key and key resolver instances, either through Azure Key Vault SDK or an external implementation.
IKeyEncryptionKey key;
IKeyEncryptionKeyResolver keyResolver;

// Create the encryption options to be used for upload and download.
ClientSideEncryptionOptions encryptionOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V2_0)
{
   KeyEncryptionKey = key,
   KeyResolver = keyResolver,
   // String value that the client library will use when calling IKeyEncryptionKey.WrapKey()
   KeyWrapAlgorithm = "some algorithm name"
};

// Set the encryption options on the client options.
BlobClientOptions options = new SpecializedBlobClientOptions() { ClientSideEncryption = encryptionOptions };

// Create blob client with client-side encryption enabled.
// Client-side encryption options are passed from service clients to container clients, 
// and from container clients to blob clients.
// Attempting to construct a BlockBlobClient, PageBlobClient, or AppendBlobClient from a BlobContainerClient
// with client-side encryption options present will throw, as this functionality is only supported with BlobClient.
BlobClient blob = new BlobServiceClient(connectionString, options).GetBlobContainerClient("my-container").GetBlobClient("myBlob");

// Upload the encrypted contents to the blob.
blob.Upload(stream);

// Download and decrypt the encrypted contents from the blob.
MemoryStream outputStream = new MemoryStream();
blob.DownloadTo(outputStream);

Puede aplicar opciones de cifrado a un constructor BlobServiceClient, BlobContainerClient o BlobClient que acepte objetos BlobClientOptions.

Si ya hay un objeto BlobClient en el código, pero no dispone de las opciones de cifrado de cliente, puede usar un método de extensión para crear una copia de ese objeto con las ClientSideEncryptionOptions especificadas. Este método de extensión evita la sobrecarga que implica construir un objeto BlobClient desde cero.

using Azure.Storage.Blobs.Specialized;

// An existing BlobClient instance and encryption options.
BlobClient plaintextBlob;
ClientSideEncryptionOptions encryptionOptions;

// Get a copy of the blob that uses client-side encryption.
BlobClient clientSideEncryptionBlob = plaintextBlob.WithClientSideEncryptionOptions(encryptionOptions);

Después de actualizar el código para usar la versión 2 del cifrado de cliente, asegúrese de descifrar y volver a cifrar los datos cifrados existentes, como se describe en la sección sobre cómo volver a cifrar datos previamente cifrados con la versión 2 del cifrado de cliente.

Nuevo cifrado de datos previamente cifrados con la versión 2 del cifrado de cliente

Los datos cifrados anteriormente con la versión 1 del cifrado de cliente se deben descifrar y, a continuación, volver a cifrar con la versión 2 del cifrado de cliente para mitigar la vulnerabilidad de seguridad. El descifrado requiere la descarga de los datos y un nuevo cifrado requiere una nueva carga de estos en Blob Storage.

Para ver un proyecto de ejemplo que muestra cómo migrar datos de la versión 1 del cifrado de cliente a la versión 2 y cómo cifrar datos con la versión 2 del cifrado de cliente en .NET, consulte el proyecto de ejemplo de migración del cifrado.

Rendimiento y cifrado de cliente

Tenga en cuenta que el cifrado de sus resultados de datos de almacenamiento da lugar a la sobrecarga de rendimiento adicional. Cuando se usa el cifrado de cliente en la aplicación, la biblioteca cliente debe generar de forma segura la CEK y el vector de inicialización, cifrar el propio contenido, comunicarse con el almacén de claves elegido para el encapsulado de claves y dar formato y cargar metadatos adicionales. Esta sobrecarga varía según la cantidad de datos que se cifran. Se recomienda que los clientes prueben siempre sus aplicaciones para obtener un rendimiento durante el desarrollo.

Pasos siguientes