Tutorial: Encriptar e desencriptar blobs com 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 com o Cofre de Chaves do Azure.

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 seus dados. Para saber mais sobre a criptografia do lado do serviço, consulte Criptografia do Armazenamento do Azure para dados em repouso.

A biblioteca de cliente 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 e descriptografar dados durante o download para o cliente. A biblioteca também oferece suporte à integração com o Azure Key Vault para gerenciamento de chaves.

Este tutorial mostrar-lhe 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 a um cofre de chaves
  • Configurar opções de criptografia do lado do cliente usando uma chave armazenada em um cofre de chaves
  • Criar um objeto cliente de serviço de blob com a criptografia do lado do cliente habilitada
  • Carregue um blob criptografado e, em seguida, baixe e descriptografe o blob

Pré-requisitos

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

Ao desenvolver localmente, certifique-se de que a conta de usuário que está acessando o cofre de chaves tenha as permissões corretas. Você precisará da função Key Vault Crypto Officer para criar uma chave e executar ações em chaves em um cofre de chaves. Você pode atribuir funções do 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, com escopo para o cofre de chaves, para seguir o Princípio do Menor Privilégio. Essa prática oferece 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 Key Vault Crypto Officer à 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 que a atribuição de função se propague no Azure, mas, em casos raros, pode levar até oito minutos. Se você receber erros de autenticação quando executar o código pela primeira vez, aguarde alguns momentos 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.

    A screenshot showing how to assign a role in Azure portal.

  5. Use a caixa de pesquisa para filtrar os resultados para a função desejada. Para este exemplo, procure Key Vault Crypto Officer e selecione o resultado correspondente e, em seguida, escolha Next.

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

  7. Na caixa de diálogo, procure seu nome de usuário do Microsoft Entra (geralmente seu endereço de e-mail user@domain ) e escolha Selecionar na parte inferior da caixa de diálogo.

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

Configure o seu projeto

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

    dotnet new console -n BlobEncryptionKeyVault
    
  2. Alterne para o diretório BlobEncryptionKeyVault recém-criado.

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

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

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

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

Adicione as seguintes using diretivas e certifique-se de adicionar uma referência ao System.Configuration 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ável de ambiente

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

Windows:

Você pode definir variáveis de ambiente para o Windows a partir da linha de comando. No entanto, ao usar essa abordagem, os valores são acessíveis a todos os aplicativos em execução nesse sistema operacional e podem causar conflitos se você não tiver 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>"

Depois de adicionar a variável de ambiente no Windows, você deve iniciar uma nova instância da janela de comando. Se você estiver usando o Visual Studio no Windows, talvez seja necessário reiniciar o Visual Studio depois de criar a variável de ambiente para que a alteração seja detetada.

Linux:

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

Adicionar uma chave no Cofre da Chave do Azure

Neste exemplo, criamos uma chave e a adicionamos ao cofre de chaves usando a biblioteca de cliente 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. O KeyClient objeto é então 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 instâncias de chave e resolvedor de chaves

Em seguida, usaremos a chave que acabamos de adicionar ao cofre para criar o cliente de criptografia e as instâncias do resolvedor de chaves. CryptographyClient implementa IKeyEncryptionKey e é usado para executar operações criptográficas com chaves armazenadas no Cofre de Chaves do Azure. 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ê tiver uma chave existente no cofre com a qual gostaria de criptografar, poderá criar a chave e as instâncias do resolvedor de chaves passando o 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 ClientSideEncryptionOptions objeto e o definimos na criação do cliente com SpecializedBlobClientOptionso .

A classe ClientSideEncryptionOptions fornece as opções de configuração do cliente para se conectar ao Armazenamento de Blob usando criptografia do lado do cliente. KeyEncryptionKey é necessária para operações de upload e é usada para encapsular a chave de criptografia de conteúdo gerada. KeyResolver é necessário para operações de download e busca a chave de criptografia de chave correta para desembrulhar a chave de criptografia de conteúdo baixado. KeyWrapAlgorithm é necessário para 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, recomenda-se construir o objeto usando ClientSideEncryptionVersion.V2_0 para o ClientSideEncryptionOptions parâmetro version. Para saber mais sobre como reduzir a vulnerabilidade em seus aplicativos, consulte Mitigar a vulnerabilidade de segurança em seus aplicativos. Para obter mais informações sobre esta vulnerabilidade de segurança, consulte Armazenamento do Azure atualizando 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 do cliente para usar a criptografia do lado do cliente

Neste exemplo, aplicamos as opções de configuração de criptografia do lado do cliente a um BlobServiceClient objeto. Quando aplicadas no nível do cliente de serviço, 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 o BlobClient objeto executa uma operação de carregamento 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 blob e carregar

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

  1. A biblioteca de cliente do Armazenamento do Azure gera um vetor de inicialização aleatória (IV) de 16 bytes e uma chave de criptografia de conteúdo aleatória (CEK) de 32 bytes e executa a criptografia de envelope dos dados de blob usando essas informações.
  2. Os dados de Blob são criptografados usando o CEK.
  3. O CEK é então encapsulado (criptografado) usando a chave de criptografia de chave (KEK) que especificamos em ClientSideEncryptionOptions. Neste exemplo, o KEK é um par de chaves assimétricas armazenado no recurso especificado do Azure Key Vault. O cliente blob em si nunca tem acesso ao KEK, ele apenas invoca o algoritmo de encapsulamento de chave que é fornecido pelo Key Vault.
  4. Os dados de blob criptografados são então carregados para a conta de armazenamento.

Adicione o seguinte código para criptografar um blob e carregá-lo em 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);

Depois que o blob for carregado, você poderá visualizá-lo em sua conta de armazenamento para ver o conteúdo criptografado junto com os metadados de criptografia.

Desencriptar blob e descarregar

A biblioteca de cliente do Armazenamento do Azure pressupõe que o usuário esteja gerenciando o KEK localmente ou em um cofre de chaves. O usuário não precisa saber 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 BlobClient objeto chama um método de download, várias etapas ocorrem para descriptografar os dados de blob criptografados:

  1. A biblioteca do cliente baixa os dados de blob criptografados, incluindo metadados de criptografia, da conta de armazenamento.
  2. O CEK encapsulado é então desembrulhado (desencriptado) usando o KEK. A biblioteca de cliente não tem acesso ao KEK durante esse processo, mas apenas invoca o algoritmo de desempacotamento de chave especificado em ClientSideEncryptionOptions. A chave privada do par de chaves RSA permanece no cofre de chaves, de modo que a chave criptografada dos metadados de blob que contém o CEK é enviada para o cofre de chaves para descriptografia.
  3. A biblioteca de cliente usa o CEK para descriptografar os dados de blob criptografados.

Adicione o seguinte código para descarregar e desencriptar o blob que 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óximos passos

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

Para obter uma ampla visão geral da criptografia do lado do cliente para blobs, incluindo 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, consulte a página de visão geral do Azure Key Vault