Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
C#chevron-right

Integrar o Azure Key Vault com a criptografia em nível de campo no lado do cliente do MongoDB

Adrienne Tacke9 min read • Published Aug 27, 2021 • Updated May 24, 2022
AzureMongoDBSegurançaC#
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Ao implementar a criptografia em nível de campodo MongoDBno lado do cliente (CSFLE), você se verá fazendo uma decisão importante: onde armazeno minha chave mestra do cliente? Em outro tutorial, oriento os leitores sobre os fundamentos do CSFLE usando uma chave mestra gerada e armazenada localmente. Embora isso funcione para fins informativos e de desenvolvimento local, não é adequado para produção! Neste tutorial, vamos ver como usar o Azure Key Vault para gerar e armazenar com segurança nossa chave mestra.

Pré-requisitos

Salto rápido

Prepare a infraestrutura do Azure
Configure seu aplicativo cliente para usar o Azure Key Vault e o CSFLE

Registrar aplicativo no Azure Active Directory

Para estabelecer uma relação de confiança entre nosso aplicativo e a plataforma de identidade da Microsoft, primeiro precisamos registrá-lo. 
  1. Inicie sessão no portal do Azure.
  2. Se você tiver acesso a vários inquilinos, no menu superior, use o “Directory + subscription filter” para selecionar o inquilino no qual você deseja registrar um aplicativo.
  3. Na barra de pesquisa principal, pesquise e selecione “Azure Active Directory.”
  4. No menu de navegação à esquerda, encontre a seção Gerenciar e selecione "App registrations," e depois "+ New registration."
  5. Insira um nome de exibição para seu aplicativo. Você pode alterar o nome de exibição a qualquer momento e vários registros de aplicativos podem compartilhar o mesmo nome. O ID do aplicativo (cliente) gerado automaticamente pelo registro do aplicativo, não seu nome de exibição, identifica seu aplicativo de forma exclusiva na plataforma de identidade.
  6. Especifique quem pode usar o aplicativo, às vezes chamado de público-alvo de login. Para este tutorial, selecionei "Accounts in this organizational directory only (Default Directory only - Single tenant)." Isso só permite que os usuários que estão no meu locatário atual acessem meu aplicativo.
  7. Clique em “Register.” Assim que o registro inicial do aplicativo for concluído, copie o ID do diretório (locatário) e o ID do aplicativo (cliente), pois precisaremos deles mais tarde.
  8. Encontre o aplicativo vinculado em "Managed application in local directory " e clique nele.
  9. Uma vez levado para a página “Properties”, copie também o “Object ID”, pois precisaremos dele também.

Crie um segredo do cliente

Depois que seu aplicativo for registrado, precisaremos criar um segredo do cliente para ele. Isso será necessário ao autenticar no Key Vault que criaremos em breve.
  1. Na visão geral do seu aplicativo recém-registrado, clique em “Add a certificate or secret”:
  2. Em “Client secrets,”, clique em “+ New client secret.”
  3. Insira uma breve descrição para este segredo do cliente e deixe a configuração padrão "Expires " de 6 meses.
  4. Clique em "Ad." Once the client secret is created, be sure to copy the secret’s “Value", pois precisaremos dele mais tarde. Também vale a pena mencionar que, depois de sair desta página, o valor secreto nunca mais será exibido, portanto, certifique-se de registrá-lo pelo menos uma vez!

Criar um Azure Key Vault

Em seguida, um Azure Key Vault! Criaremos uma para que possamos armazenar com segurança a chave mestra do cliente. Estaremos concluindo estas etapas por meio da CLI do Azure, então abra seu terminal favorito e acompanhe:
  1. Entre no Azure CLI utilizando o  comandoaz login . Conclua as etapas de autenticação seguindo as etapas exibidas no seu terminal.
  2. Crie um grupo de recursos: 
    1az group create --name "YOUR-RESOURCE-GROUP-NAME" --location <YOUR-AZURE-REGION>
  3. Crie um cofre de chaves: 
    1az keyvault create --name "YOUR-KEYVAULT-NAME" --resource-group "YOUR-RESOURCE-GROUP-NAME" --location <YOUR-AZURE-REGION>

Crie e adicione uma chave ao seu Key Vault

Com um cofre de chaves, agora podemos criar nossa chave mestra do cliente! Isso será armazenado, gerenciado e protegido pelo Azure Key Vault.
Criar uma chave e adicionar ao nosso cofre de chaves:
1az keyvault key create --vault-name "YOUR-KEYVAULT-NAME" --name "YOUR-KEY-NAME" --protection software
O parâmetro --protectiondesigna otipo de proteção de chave. Por enquanto, usaremos o tiposoftware. Quando o comando for concluído, anote o "nome" da sua chave, pois precisaremos dela mais tarde!

Conceder permissões de aplicativo para o Key Vault

Para habilitar o acesso do aplicativo do cliente ao cofre de chaves, algumas permissões precisam ser concedidas:
  1. Dê ao seu aplicativo as permissõeswrapKey e unwrapKey para o keyvault. (Para o parâmetro--object-id, cole o ID do objeto do aplicativo que registramos anteriormente. Esse é o ID do objeto que copiamos na última etapa "Registrar aplicativo no Azure Active Directory".)
    1az keyvault set-policy --name "YOUR-KEYVAULT-NAME" --key-permissions wrapKey unwrapKey --object-id <YOUR-APP-OBJECT-ID>
  2. Após o sucesso, você receberá um objeto JSON. Encontre e copie o valor da chave "vaultUri ". Por exemplo, o meu é https://csfle-mdb-demo-vault.vault.azure.net.

Integrar o Azure Key Vault ao seu aplicativo cliente

Agora que nossa infraestrutura em nuvem está configurada, podemos começar a integrá-la ao nosso aplicativo. Faremos referência ao repositório de amostraa partir de nossos pré-requisitos para essas etapas, mas fique à vontade para usar as partes necessárias em um aplicativoexistente.
  1. Se você ainda não clonou o repositório, faça isso agora! 
    1git clone https://github.com/adriennetacke/mongodb-csfle-csharp-demo-azure.git
  2. Navegue até o diretório raiz mongodb-csfle-csharp-demo-azure e abra o aplicativo de amostraEnvoyMedSysno Visual Studio.
  3. No Solution Explorer, localize e abra o arquivolaunchSettings.json(Properties > launchSettings.json).
  4. Aqui, você verá alguns andaimes para algumas variáveis. Vamos Go rapidamente o que são:
    • MDB_ATLAS_URIA string de conexão para o seu cluster do MongoDB Atlas. Isso nos permite armazenar nossa chave de encriptação de dados, criptografada pelo Azure Key Vault.
    • AZURE_TENANT_IDIdentifica a organização da conta do Azure.
    • AZURE_CLIENT_ID: Identifica o clientId para autenticar seu aplicativo registrado.
    • AZURE_CLIENT_SECRETUsado para autenticar seu aplicativo registrado.
    • AZURE_KEY_NAMENome da Chave Mestra do Cliente armazenada no Azure Key Vault.
    • AZURE_KEYVAULT_ENDPOINT: URL do Key Vault. Por exemplo, yourVaultName.vault.azure.net.
  5. Substitua todos os espaços reservados no arquivo launchSettings.jsonporsuas próprias informações. Cada variável corresponde a um valor que você foi solicitado para copiar e acompanhar:
    • MDB_ATLAS_URI: o URI do seu Atlas.
    • AZURE_TENANT_IDID do diretório (locatário).
    • AZURE_CLIENT_IDID do aplicativo (cliente).
    • AZURE_CLIENT_SECRET:valorsecreto do segredo do cliente.
    • AZURE_KEY_NAME:Nomeda Chave.
    • AZURE_KEYVAULT_ENDPOINT : vaultUrido nosso Key Vault.
  6. Salve todos os seus arquivos!
Antes de executarmos o aplicativo, vamos analisar o que está acontecendo: quando executamos nosso programa principal, definimos a conexão com o cluster Atlas e o namespace da collection do cofre de chaves. Em seguida, instanciamos duas classes auxiliares:KmsKeyHelper e AutoEncryptHelper. O KmsKeyHelper CreateKeyWithAzureKmsProvider() método do é chamado para gerar nossa chave de criptografia de dados criptografados. Em seguida, isso é passado para o AutoEncryptHelper EncryptedWriteAndReadAsync() método do para inserir um documento de amostra com campos criptografados e descriptografá-lo adequadamente quando precisarmos buscá-lo. Tudo isso está em nosso Program.cs arquivo :
Program.cs
1using System;
2using MongoDB.Driver;
3
4namespace EnvoyMedSys
5{
6 public enum KmsKeyLocation
7 {
8 Azure,
9 }
10
11 class Program
12 {
13 public static void Main(string[] args)
14 {
15 var connectionString = Environment.GetEnvironmentVariable("MDB_ATLAS_URI");
16 var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVaultTemp");
17
18 var kmsKeyHelper = new KmsKeyHelper(
19 connectionString: connectionString,
20 keyVaultNamespace: keyVaultNamespace);
21 var autoEncryptHelper = new AutoEncryptHelper(
22 connectionString: connectionString,
23 keyVaultNamespace: keyVaultNamespace);
24
25 var kmsKeyIdBase64 = kmsKeyHelper.CreateKeyWithAzureKmsProvider().GetAwaiter().GetResult();
26
27 autoEncryptHelper.EncryptedWriteAndReadAsync(kmsKeyIdBase64, KmsKeyLocation.Azure).GetAwaiter().GetResult();
28
29 Console.ReadKey();
30 }
31 }
32}
Dando uma olhada na classeKmsKeyHelper, há alguns métodos importantes: os métodos CreateKeyWithAzureKmsProvider() e GetClientEncryption(). Optou por incluir comentários no código para facilitar o acompanhamento:
KmsKeyHelper.csCreateKeyWithAzureKmsProvider()
1public async Task<string> CreateKeyWithAzureKmsProvider()
2{
3 var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
4
5 // Pull Azure Key Vault settings from environment variables
6 var azureTenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
7 var azureClientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
8 var azureClientSecret = Environment.GetEnvironmentVariable("AZURE_CLIENT_SECRET");
9 var azureIdentityPlatformEndpoint = Environment.GetEnvironmentVariable("AZURE_IDENTIFY_PLATFORM_ENPDOINT"); // Optional, only needed if user is using a non-commercial Azure instance
10
11 // Configure our registered application settings
12 var azureKmsOptions = new Dictionary<string, object>
13 {
14 { "tenantId", azureTenantId },
15 { "clientId", azureClientId },
16 { "clientSecret", azureClientSecret },
17 };
18
19 if (azureIdentityPlatformEndpoint != null)
20 {
21 azureKmsOptions.Add("identityPlatformEndpoint", azureIdentityPlatformEndpoint);
22 }
23
24 // Specify remote key location; in this case, Azure
25 kmsProviders.Add("azure", azureKmsOptions);
26
27 // Constructs our client encryption settings which
28 // specify which key vault client, key vault namespace,
29 // and KMS providers to use.
30 var clientEncryption = GetClientEncryption(kmsProviders);
31
32 // Set KMS Provider Settings
33 // Client uses these settings to discover the master key
34 var azureKeyName = Environment.GetEnvironmentVariable("AZURE_KEY_NAME");
35 var azureKeyVaultEndpoint = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_ENDPOINT"); // typically <azureKeyName>.vault.azure.net
36 var azureKeyVersion = Environment.GetEnvironmentVariable("AZURE_KEY_VERSION"); // Optional
37 var dataKeyOptions = new DataKeyOptions(
38 masterKey: new BsonDocument
39 {
40 { "keyName", azureKeyName },
41 { "keyVaultEndpoint", azureKeyVaultEndpoint },
42 { "keyVersion", () => azureKeyVersion, azureKeyVersion != null }
43 });
44
45 // Create Data Encryption Key
46 var dataKeyId = clientEncryption.CreateDataKey("azure", dataKeyOptions, CancellationToken.None);
47 Console.WriteLine($"Azure DataKeyId [UUID]: {dataKeyId}");
48
49 var dataKeyIdBase64 = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));
50 Console.WriteLine($"Azure DataKeyId [base64]: {dataKeyIdBase64}");
51
52 // Optional validation; checks that key was created successfully
53 await ValidateKeyAsync(dataKeyId);
54
55 return dataKeyIdBase64;
56}

KmsKeyHelper.cs / GetClientEncryption()
1private ClientEncryption GetClientEncryption(
2 Dictionary<string, IReadOnlyDictionary<string, object>> kmsProviders)
3{
4 // Construct a MongoClient using our Atlas connection string
5 var keyVaultClient = new MongoClient(_mdbConnectionString);
6
7 // Set MongoClient, key vault namespace, and Azure as KMS provider
8 var clientEncryptionOptions = new ClientEncryptionOptions(
9 keyVaultClient: keyVaultClient,
10 keyVaultNamespace: _keyVaultNamespace,
11 kmsProviders: kmsProviders);
12
13 return new ClientEncryption(clientEncryptionOptions);
14}
Com o Azure Key Vault conectado e a chave de encriptação de dados criptografada, estamos prontos para inserir alguns dados em nosso Atlas cluster! É aqui que entra a classe AutoEncryptHelper . O método importante a ser observado aqui é o métodoEncryptedReadAndWrite():
AutoEncryptHelper.cs / EncryptedReadAndWrite()
1public async Task EncryptedWriteAndReadAsync(string keyIdBase64, KmsKeyLocation kmsKeyLocation)
2{
3 // Construct a JSON Schema
4 var schema = JsonSchemaCreator.CreateJsonSchema(keyIdBase64);
5
6 // Construct an auto-encrypting client
7 var autoEncryptingClient = CreateAutoEncryptingClient(
8 kmsKeyLocation,
9 _keyVaultNamespace,
10 schema);
11
12 // Set our working database and collection to medicalRecords.patientData
13 var collection = autoEncryptingClient
14 .GetDatabase(_medicalRecordsNamespace.DatabaseNamespace.DatabaseName)
15 .GetCollection<BsonDocument>(_medicalRecordsNamespace.CollectionName);
16
17 var ssnQuery = Builders<BsonDocument>.Filter.Eq("ssn", __sampleSsnValue);
18
19 // Upsert (update if found, otherwise create it) a document into the collection
20 var medicalRecordUpdateResult = await collection
21 .UpdateOneAsync(ssnQuery, new BsonDocument("$set", __sampleDocFields), new UpdateOptions() { IsUpsert = true });
22
23 if (!medicalRecordUpdateResult.UpsertedId.IsBsonNull)
24 {
25 Console.WriteLine("Successfully upserted the sample document!");
26 }
27
28 // Query by SSN field with auto-encrypting client
29 var result = await collection.Find(ssnQuery).SingleAsync();
30
31 // Proper result in console should show decrypted, human-readable document
32 Console.WriteLine($"Encrypted client query by the SSN (deterministically-encrypted) field:\n {result}\n");
33}
Agora que sabemos o que está rolando, execute seu aplicativo!

Os resultados: o que você obtém após integrar o Azure Key Vault com o MongoDB CSFLE

Se tudo correr bem, seu console imprimirá dois DataKeyIds (UUID e64 base ) e um documento semelhante ao seguinte: 
Sample Result Document (using my information)
1{
2 _id:UUID('ab382f3e-bc79-4086-8418-836a877efff3'),
3keyMaterial:Binary('tvehP03XhUsztKr69lxlaGjiPhsNPjy6xLhNOLTpe4pYMeGjMIwvvZkzrwLRCHdaB3vqi9KKe6/P5xvjwlVHacQ1z9oFIwFbp9nk...', 0),
4 creationDate:2021-08-24T05:01:34.369+00:00,
5 updateDate:2021-08-24T05:01:34.369+00:00,
6 status:0,
7 masterKey:Object,
8 provider:"azure",
9 keyVaultEndpoint:"csfle-mdb-demo-vault.vault.azure.net",
10 keyName:"MainKey"
11}
Veja como é a saída do meu console, para referência:
Captura de tela da saída do console mostrando dois Azure DatakeyIds e um documento não formatado
Ver isso é uma ótima notícia! Muitas coisas acabaram de acontecer, e todas elas são boas:
  • Nosso aplicativo foi autenticado corretamente em nosso Azure Key Vault.
  • Uma chave de criptografia de dados gerada corretamente foi criada pelo nosso aplicativo cliente.
  • A chave de criptografia de dados foi criptografada corretamente pela chave mestra do cliente que está armazenada com segurança no Azure Key Vault.
  • A chave de encriptação de dados criptografada foi retornada ao nosso aplicativo e armazenada em nosso MongoDB Atlas cluster.

Aqui está o mesmo processo em um fluxo de trabalho:
Diagrama de fluxo de trabalho de como uma chave de encriptação de dados é configurada com um provedor de KMS. O aplicativo cliente cria uma chave de criptografia de dados não criptografada que solicita criptografia do Azure Key Vault (o provedor de KMS). usando a Chave Mestra do Cliente, o Azure Key Vault criptografa a chave de criptografia de dados e a envia de volta para o aplicativo cliente, que armazena a chave criptografada na coleção do cofre de chaves do MongoDB.
Depois de mais alguns instantes, e após o sucesso, você verá uma mensagem "Successfully upserted the sample document!", seguida pelos resultados devidamente descriptografados de uma consulta de teste. Novamente, aqui está a saída do meu console para referência:
Captura de tela da saída do console mostrando uma mensagem "Successfully upserted the sample document message!" seguida por um documento legível por humanos dos dados de um paciente de amostra, incluindo os campos SSN e policyNumber devidamente descriptografados.
Isso significa que nosso documento de amostra foi criptografado corretamente, inserido em nossa coleção patientData, consultado com nosso cliente de criptografia automática por SSN e teve todos os campos relevantes descriptografados corretamente antes de retorná-los ao nosso console. Que legal!
E só por ser um pouco paranóia, podemos verificar se nossos dados foram realmente criptografados. Se você fizer login em seu Atlas cluster e navegar até a coleçãopatientData, verá que os campos confidenciais de nossos documentos estão todos ilegíveis:
Captura de tela do documento criptografado no cluster do Atlas. Mostra os campos SSN, BloodType, PolyNumber, MedicalRecord como asteriscos e outros campos como legíveis.

Vamos resumir

Isso não foi tão ruim, certo? Vamos ver o que conseguimos! Este tutorial mostrou a você:
  • Registrando um aplicativo no Azure Active Directory.
  • Criando um segredo do cliente.
  • Criando um Azure Key Vault.
  • Criar e adicionar uma chave ao seu Key Vault.
  • Concedendo permissões de aplicativo para o Key Vault.
  • Integrando o Azure Key Vault ao seu aplicativo cliente.
  • Os resultados: o que você obtém após integrar o Azure Key Vault com o MongoDB CSFLE.
Ao usar um sistema de gerenciamento de chaves remoto como o Azure Key Vault, você obtém acesso a muitos benefícios em relação ao uso de um sistema de arquivos local. O mais importante deles é o armazenamento seguro da chave, risco reduzido de problemas de permissão de acesso e portabilidade mais fácil!
Para obter mais informações, confira esta lista útil de recursos que usei ao preparar este tutorial:
E se você tiver alguma dúvida ou precisar de ajuda adicional, não deixe de nos consultar nos fóruns daMongoDB Community  e iniciar um tópico!
Uma comunidade inteira de engenheiros do MongoDB (incluindo a equipe DevRel) e outros desenvolvedores com certeza ajudarão!

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Crie uma API RESTful com .NET Core e MongoDB


Sep 11, 2024 | 8 min read
Tutorial

Unindo coleções no MongoDB com .NET Core e um pipeline de agregação


Feb 03, 2023 | 7 min read
Início rápido

MongoDB e C Sharp: tutorial de operações CRUD


Sep 23, 2022 | 12 min read
Tutorial

Trabalhando com transações MongoDB com C# e .NET Framework


Sep 11, 2024 | 3 min read
Sumário