Tutorial: criptografar e descriptografar blobs usando o Cofre de Chaves do Azure

Neste tutorial, você aprenderá a usar a criptografia do lado do cliente para criptografar e descriptografar blobs usando uma chave armazenada no Azure Key Vault.

O Armazenamento de Blobs do Azure dá suporte à criptografia do lado do serviço e do lado do cliente. Para a maioria dos cenários, a Microsoft recomenda o uso de recursos de criptografia do lado do serviço para facilitar o uso na proteção de dados. Para saber mais sobre a criptografia do lado do serviço, confira Criptografia do Armazenamento do Azure para dados inativos.

A Biblioteca de clientes do Armazenamento de Blobs do Azure para .NET dá suporte à criptografia de dados do lado do cliente em aplicativos antes de carregar no Armazenamento do Azure, bem como à descriptografia de dados durante o download para o cliente. A biblioteca também dá suporte à integração com o Azure Key Vault para o gerenciamento de chaves.

Este tutorial mostra como:

  • Configurar permissões para um recurso do Azure Key Vault
  • Criar um aplicativo de console para interagir com recursos usando bibliotecas de cliente .NET
  • Adicionar uma chave ao cofre de chaves
  • Configurar opções de criptografia do lado do cliente usando uma chave armazenada em um cofre de chaves
  • Criar um objeto de cliente do serviço de blob com a criptografia do lado do cliente habilitada
  • Carregar um blob criptografado, baixar e descriptografar o blob

Pré-requisitos

Atribuir uma função ao usuário do Microsoft Entra

Ao desenvolver localmente, verifique se a conta de usuário acessando o cofre de chaves tem as permissões corretas. Você precisará da função Responsável pela criptografia do Key Vault para criar uma chave e executar ações em chaves em um cofre de chaves. É possível atribuir funções RBAC do Azure a um usuário usando o portal do Azure, a CLI do Azure ou o Azure PowerShell. Você pode saber mais sobre os escopos disponíveis para atribuições de função na página de visão geral do escopo.

Nesse cenário, você atribuirá permissões à sua conta de usuário, no escopo do cofre de chaves, para seguir o Princípio do Privilégio Mínimo. Essa prática fornece aos usuários apenas as permissões mínimas necessárias e cria ambientes de produção mais seguros.

O exemplo a seguir mostra como atribuir a função Responsável pela criptografia do Key Vault à sua conta de usuário, que fornece o acesso necessário para concluir este tutorial.

Importante

Na maioria dos casos, levará um ou dois minutos para a atribuição de função se propagar no Azure, mas em casos raros pode levar até oito minutos. Se você receber erros de autenticação ao executar o código pela primeira vez, aguarde alguns instantes e tente novamente.

  1. No portal do Azure, localize seu cofre de chaves usando a barra de pesquisa principal ou a navegação à esquerda.

  2. Na página de visão geral do cofre de chaves, selecione Controle de acesso (IAM) no menu à esquerda.

  3. Na página Controle de acesso (IAM), selecione a guia Atribuições de função.

  4. Selecione + Adicionar no menu superior e, em seguida, Adicionar atribuição de função no menu suspenso resultante.

    Captura de tela mostrando como atribuir uma função no portal do Azure.

  5. Use a caixa de pesquisa para filtrar os resultados para a função desejada. Para este exemplo, pesquise por Responsável pela criptografia do Key Vault, selecione o resultado correspondente e escolha Avançar.

  6. Em Atribuir acesso a, selecione Usuário, grupo ou entidade de serviço e, em seguida, selecione + Selecionar membros.

  7. No diálogo, pesquise seu nome de usuário do Microsoft Entra (geralmente seu endereço de email user@domain) e escolha Selecionar na parte inferior do diálogo.

  8. Selecione Revisar + atribuir para ir para a página final e, em seguida, Revisar + atribuir novamente para concluir o processo.

Configurar o seu projeto

  1. Em uma janela do console (como PowerShell ou Bash), use o comando dotnet new para criar um novo aplicativo do console com o nome BlobEncryptionKeyVault. Esse comando cria um projeto simples C# "Olá, Mundo" com um arquivo de origem único: Program.cs.

    dotnet new console -n BlobEncryptionKeyVault
    
  2. Alterne para o diretório BlobEncryptionKeyVault criado recentemente.

    cd BlobEncryptionKeyVault
    
  3. Abra o projeto no editor de código desejado. Para abrir o projeto no:

    • Visual Studio, localize e clique duas vezes no arquivo BlobEncryptionKeyVault.csproj.
    • Execute o seguinte comando no Visual Studio Code:
    code .
    

Para interagir com os serviços do Azure neste exemplo, instale as bibliotecas de cliente a seguir usando dotnet add package.

dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Keys
dotnet add package Azure.Storage.Blobs

Adicione as seguintes diretivas do using e adicione uma referência a System.Configuration ao projeto.

using Azure;
using Azure.Core;
using Azure.Identity;
using Azure.Security.KeyVault.Keys;
using Azure.Security.KeyVault.Keys.Cryptography;
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;

Definir variáveis de ambiente

Esse aplicativo procura uma variável de ambiente chamada KEY_VAULT_NAME para recuperar o nome do cofre de chaves. Para definir a variável de ambiente, abra uma janela de console e siga as instruções do seu sistema operacional. Substitua <your-key-vault-name> pelo nome do cofre de chaves.

Windows:

Você pode definir variáveis de ambiente para Windows na linha de comando. No entanto, quando se usa essa abordagem, os valores são acessíveis a todos os aplicativos em execução nesse sistema operacional e poderão causar conflitos se você não tomar cuidado. As variáveis de ambiente podem ser definidas no nível do usuário ou do sistema:

setx KEY_VAULT_NAME "<your-key-vault-name>"

Após adicionar a variável de ambiente no Windows, é necessário iniciar uma nova instância da janela de comando. No caso do Visual Studio do Windows, ele pode precisar ser reiniciado depois da criação da variável de ambiente para que a alteração seja detectada.

Linux:

export KEY_VAULT_NAME=<your-key-vault-name>

Adicionar uma chave no Azure Key Vault

Neste exemplo, criamos uma chave e a adicionamos ao cofre de chaves usando a biblioteca de clientes do Azure Key Vault. Você também pode criar e adicionar uma chave a um cofre de chaves usando a CLI do Azure, o portal do Azure ou o PowerShell.

No exemplo abaixo, criamos um objeto KeyClient para o cofre especificado. Em seguida, o objeto KeyClient é usado para criar uma nova chave RSA no cofre especificado.

var keyName = "testRSAKey";
var keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");

// URI for the key vault resource
var keyVaultUri = $"https://{keyVaultName}.vault.azure.net";

TokenCredential tokenCredential = new DefaultAzureCredential();

// Create a KeyClient object
var keyClient = new KeyClient(new Uri(keyVaultUri), tokenCredential);

// Add a key to the key vault
var key = await keyClient.CreateKeyAsync(keyName, KeyType.Rsa);

Criar chave e instâncias de resolvedor de chave

Em seguida, usaremos a chave que acabamos de adicionar ao cofre para criar o cliente de criptografia e as instâncias de resolvedor de chave. A CryptographyClient implementa IKeyEncryptionKey e é usada para executar operações criptográficas com chaves armazenadas no Azure Key Vault. A KeyResolver implementa IKeyEncryptionResolver e recupera chaves de criptografia de chave do identificador de chave e resolve a chave.

// Cryptography client and key resolver instances using Azure Key Vault client library
CryptographyClient cryptoClient = keyClient.GetCryptographyClient(key.Value.Name, key.Value.Properties.Version);
KeyResolver keyResolver = new (tokenCredential);

Se você já tiver uma chave no cofre com a qual gostaria de criptografar, é possível criar a chave e as instâncias de resolvedor de chave passando no URI:

var keyVaultKeyUri = $"https://{keyVaultName}.vault.azure.net/keys/{keyName}";
CryptographyClient cryptoClient = new CryptographyClient(new Uri(keyVaultKeyUri), tokenCredential);

Configurar opções de criptografia

Agora, precisamos configurar as opções de criptografia a serem usadas para upload e download de blob. Para usar a criptografia do lado do cliente, primeiro criamos um objeto ClientSideEncryptionOptions e o definimos na criação do cliente com SpecializedBlobClientOptions.

A classe ClientSideEncryptionOptions fornece as opções de configuração do cliente para se conectar ao Armazenamento de Blobs usando a criptografia do lado do cliente. A KeyEncryptionKey é necessária para operações de upload e é usada para encapsular a chave de criptografia de conteúdo gerada. A KeyResolver é necessária para operações de download e busca a chave de criptografia de chave correta para desencapsular a chave de criptografia de conteúdo baixada. A KeyWrapAlgorithm é necessária em uploads e especifica o identificador de algoritmo a ser usado ao encapsular a chave de criptografia de conteúdo.

Importante

Devido a uma vulnerabilidade de segurança na versão 1, é recomendável construir o objeto ClientSideEncryptionOptions usando ClientSideEncryptionVersion.V2_0 para o parâmetro de versão. Para saber mais sobre como reduzir a vulnerabilidade em seus aplicativos, consulte Reduzir a vulnerabilidade de segurança em aplicativos. Para saber mais sobre essa vulnerabilidade de segurança, confira Armazenamento do Azure atualiza a criptografia do lado do cliente no SDK para resolver a vulnerabilidade de segurança.

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

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

Configurar o objeto cliente para usar a criptografia do lado do cliente

Neste exemplo, aplicamos as opções de configuração da criptografia do lado do cliente a um objeto BlobServiceClient. Essas opções de criptografia são passadas do cliente de serviço para clientes de contêiner e de clientes de contêiner para clientes de blob, quando aplicadas no nível do cliente de serviço. Quando o objeto BlobClient executa uma operação de upload ou download, as bibliotecas de cliente do Armazenamento de Blobs do Azure usam criptografia de envelope para criptografar e descriptografar blobs no lado do cliente. A criptografia de envelope criptografa uma chave com uma ou mais chaves adicionais.

// Create a blob client with client-side encryption enabled.
// 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.
Uri blobUri = new (string.Format($"https://{accountName}.blob.core.windows.net"));
BlobClient blob = new BlobServiceClient(blobUri, tokenCredential, options).GetBlobContainerClient("test-container").GetBlobClient("testBlob");

Criptografar o blob e carregar

Quando o objeto BlobClient chama um método de upload, ocorrem várias etapas para executar a criptografia do lado do cliente:

  1. A biblioteca de clientes do Armazenamento do Microsoft Azure gera um IV (vetor de inicialização) aleatório de 16 bytes, uma CEK (chave de criptografia aleatória de conteúdo) de 32 bytes e executa a criptografia de envelope dos dados do blob usando essas informações.
  2. Os dados do blob são criptografados usando a CEK.
  3. Em seguida, a CEK é empacotada (criptografada) usando o KEK (Chave de criptografia de chave) especificada em ClientSideEncryptionOptions. Neste exemplo, a KEK é um par de chaves assimétricas armazenado no recurso do Azure Key Vault especificado. O próprio cliente blob nunca tem acesso à KEK, ele apenas invoca o algoritmo de encapsulamento de chave fornecido pelo Key Vault.
  4. Os dados do blob criptografados são carregados na conta de armazenamento.

Adicione o seguinte código para criptografar um blob e fazer upload dele na sua conta de armazenamento do Azure:

// Upload the encrypted contents to the blob
Stream blobContent = BinaryData.FromString("Ready for encryption, Captain.").ToStream();
await blob.UploadAsync(blobContent);

Após o upload do blob, é possível exibir o blob em sua conta de armazenamento para ver o conteúdo criptografado junto aos metadados de criptografia.

Descriptografar o blob e baixar

A biblioteca de clientes do Armazenamento do Azure considera que o usuário está gerenciando a KEK localmente ou em um cofre de chaves. O usuário não precisa conhecer a chave específica que foi usada para criptografia. O resolvedor de chaves especificado em ClientSideEncryptionOptions será usado para resolver identificadores de chave quando os dados de blob forem baixados e descriptografados.

Quando o objeto BlobClient chama um método de download, ocorrem várias etapas para descriptografar os dados de blob criptografados:

  1. A biblioteca de clientes faz o download dos dados de blob criptografados, incluindo metadados de criptografia, da conta de armazenamento.
  2. Em seguida, a CEK encapsulada é desencapsulada (descriptografada) usando a KEK. A biblioteca de clientes não tem acesso à KEK durante esse processo, mas invoca apenas o algoritmo de desencapsulamento de chaves especificado em ClientSideEncryptionOptions. A chave privada do par de chaves RSA permanece no cofre da chaves, assim a chave criptografada do metadados de blob que contêm a CEK é enviada ao cofre da chave para descriptografia.
  3. A biblioteca de clientes usa a CEK para descriptografar os dados de blobs criptografados.

Adicionar o código a seguir para fazer download e descriptografar o blob que você carregou anteriormente.

// Download and decrypt the encrypted contents from the blob
Response<BlobDownloadInfo>  response = await blob.DownloadAsync();
BlobDownloadInfo downloadInfo = response.Value;
Console.WriteLine((await BinaryData.FromStreamAsync(downloadInfo.Content)).ToString());

Próximas etapas

Neste tutorial, você aprendeu a usar bibliotecas de clientes do .NET para executar a criptografia do lado do cliente em operações de upload e download de blobs.

Para obter uma visão geral abrangente da criptografia do lado do cliente para blobs, inclusive instruções para migrar dados criptografados para a versão 2, consulte Criptografia do lado do cliente para blobs.

Para obter mais informações sobre o Azure Key Vault, confira a Página de visão geral do Azure Key Vault