Menu Docs
Página inicial do Docs
/ / /
Driver de fluxos reativos do Java
/

Criptografia do lado do cliente

Nesta página

  • Instalação
  • libmongocrypt
  • Configuração do mongocryptd
  • Exemplos
  • criptografia explícita e descriptografia
  • Criptografia explícita e descriptografia automática

Começando em v4.2, O MongoDB oferece suporte à criptografia do lado do cliente. A criptografia do lado do cliente permite que administradores e desenvolvedores criptografem campos de dados específicos, além de fornecer outros recursos de criptografia MongoDB.

Com a criptografia em nível de campo, os desenvolvedores podem criptografar campos no lado do cliente sem nenhuma configuração ou diretiva no lado do servidor. A criptografia no nível do campo no lado do cliente oferece suporte a cargas de trabalho em que os aplicativos devem garantir que partes não autorizadas, incluindo administradores de servidor, não possam ler os dados criptografados.

Importante

Este guia usa as implementações do Subscriber , que são descritas noPrimário de Início Rápidodo .

A maneira recomendada de começar a usar a criptografia em nível de campo em seu projeto é usando um sistema de gerenciamento de dependências. A criptografia em nível de campo requer pacotes adicionais além do driver.

Observação

Para obter instruções sobre como instalar o driver Java Reactive Streams, consulte o guia de instalação.

Há um arquivo JAR separado contendo vinculações do libmongocrypt .

Se você estiver usando o Maven para gerenciar seus pacotes, adicione a seguinte entrada à sua pom.xml lista de dependências do :

<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-crypt</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>

Se você estiver usando o Gradle para gerenciar seus pacotes, adicione a seguinte entrada à sua lista de dependências:

dependencies {
implementation 'org.mongodb:mongodb-crypt:1.2.1'
}

As vinculações do libmongocrypt exigem que o daemon/processo do mongocryptd esteja em execução. Um URI de daemon/processo específico pode ser configurado na classe AutoEncryptionSettings definindo mongocryptdURI na configuração extraOptions .

O exemplo a seguir é um aplicativo que pressupõe que a chave e o esquema já foram criados no MongoDB. O exemplo usa uma chave local, mas você também pode usar o AWS/Azure/GCP KMS. Os dados no campo encryptedField são automaticamente criptografados na inserção e descriptografados ao usar localizar no lado do cliente.

O exemplo de código é do ClientSideEncryptionSimpleTour.java no repositório GitHub do código fonte do driver.

import com.mongodb.AutoEncryptionSettings;
import com.mongodb.MongoClientSettings;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import com.mongodb.reactivestreams.client.MongoCollection;
import org.bson.Document;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
public class ClientSideEncryptionSimpleTour {
public static void main(final String[] args) {
// This would have to be the same master key as was used to create the encryption key
final byte[] localMasterKey = new byte[96];
new SecureRandom().nextBytes(localMasterKey);
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>() {{
put("local", new HashMap<String, Object>() {{
put("key", localMasterKey);
}});
}};
String keyVaultNamespace = "admin.datakeys";
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
MongoClientSettings clientSettings = MongoClientSettings.builder()
.autoEncryptionSettings(autoEncryptionSettings)
.build();
MongoClient mongoClient = MongoClients.create(clientSettings);
MongoCollection<Document> collection = mongoClient.getDatabase("test").getCollection("coll");
ObservableSubscriber<Void> successSubscriber = new OperationSubscriber<>();
collection.drop().subscribe(successSubscriber);
successSubscriber.await();
successSubscriber = new OperationSubscriber<>();
collection.insertOne(new Document("encryptedField", "123456789")).subscribe(successSubscriber);
successSubscriber.await();
ObservableSubscriber<Document> documentSubscriber = new PrintDocumentSubscriber();
collection.find().first().subscribe(documentSubscriber);
documentSubscriber.await();
}
}

Observação

A criptografia automática é um recurso somente para empresas .

O exemplo seguinte mostra como configurar a instância do AutoEncryptionSettings para criar uma nova chave e configurar o mapa de JSON schema.

O exemplo de código é do ClientSideEncryptionAutoEncryptionSettingsTour.java no Github repositório do do código fonte do driver.

import com.mongodb.ClientEncryptionSettings;
import com.mongodb.ConnectionString;
import com.mongodb.client.model.vault.DataKeyOptions;
import com.mongodb.client.vault.ClientEncryption;
import com.mongodb.client.vault.ClientEncryptions;
import org.bson.BsonBinary;
import org.bson.BsonDocument;
import java.util.Base64;
...
String keyVaultNamespace = "admin.datakeys";
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("mongodb://localhost"))
.build())
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
BsonBinary dataKeyId = clientEncryption.createDataKey("local", new DataKeyOptions());
final String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData());
final String dbName = "test";
final String collName = "coll";
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.schemaMap(new HashMap<String, BsonDocument>() {{
put(dbName + "." + collName,
// Need a schema that references the new data key
BsonDocument.parse("{"
+ " properties: {"
+ " encryptedField: {"
+ " encrypt: {"
+ " keyId: [{"
+ " \"$binary\": {"
+ " \"base64\": \"" + base64DataKeyId + "\","
+ " \"subType\": \"04\""
+ " }"
+ " }],"
+ " bsonType: \"string\","
+ " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic\""
+ " }"
+ " }"
+ " },"
+ " \"bsonType\": \"object\""
+ "}"));
}}).build();

A criptografia e descriptografia explícitas são um recurso MongoDB Community e não usam o processo mongocryptd . A criptografia explícita é fornecida pela classe ClientEncryption .

O exemplo de código é de ClientSideEncryptionExplicitEncryptionAndDecryptionTour.java no Github repositório do do código fonte do driver.

// This would have to be the same master key as was used to create the encryption key
final byte[] localMasterKey = new byte[96];
new SecureRandom().nextBytes(localMasterKey);
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>() {{
put("local", new HashMap<String, Object>() {{
put("key", localMasterKey);
}});
}};
MongoNamespace keyVaultNamespace = new MongoNamespace("encryption.testKeyVault");
MongoClientSettings clientSettings = MongoClientSettings.builder().build();
MongoClient mongoClient = MongoClients.create(clientSettings);
// Set up the key vault for this example
MongoCollection<Document> keyVaultCollection = mongoClient
.getDatabase(keyVaultNamespace.getDatabaseName())
.getCollection(keyVaultNamespace.getCollectionName());
ObservableSubscriber<Void> successSubscriber = new OperationSubscriber<>();
keyVaultCollection.drop().subscribe(successSubscriber);
successSubscriber.await();
// Ensure that two data keys cannot share the same keyAltName.
ObservableSubscriber<String> indexSubscriber = new OperationSubscriber<>();
keyVaultCollection.createIndex(Indexes.ascending("keyAltNames"),
new IndexOptions().unique(true)
.partialFilterExpression(Filters.exists("keyAltNames")))
.subscribe(indexSubscriber);
indexSubscriber.await();
MongoCollection<Document> collection = mongoClient.getDatabase("test").getCollection("coll");
successSubscriber = new OperationSubscriber<>();
collection.drop().subscribe(successSubscriber);
successSubscriber.await();
// Create the ClientEncryption instance
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("mongodb://localhost"))
.build())
.keyVaultNamespace(keyVaultNamespace.getFullName())
.kmsProviders(kmsProviders)
.build();
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
BsonBinary dataKeyId = clientEncryption.createDataKey("local", new DataKeyOptions());
// Explicitly encrypt a field
BsonBinary encryptedFieldValue = clientEncryption.encrypt(new BsonString("123456789"),
new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
ObservableSubscriber<InsertOneResult> insertOneSubscriber = new OperationSubscriber<>();
collection.insertOne(new Document("encryptedField", encryptedFieldValue))
.subscribe(insertOneSubscriber);
insertOneSubscriber.await();
ObservableSubscriber<Document> documentSubscriber = new OperationSubscriber<>();
collection.find().first().subscribe(documentSubscriber);
Document doc = documentSubscriber.get().get(0);
System.out.println(doc.toJson());
// Explicitly decrypt the field
System.out.println(
clientEncryption.decrypt(new BsonBinary(doc.get("encryptedField", Binary.class).getData()))
);

Embora a criptografia automática exija MongoDB 4.2 enterprise ou um cluster do Atlas MongoDB 4.2, a descriptografia automática é suportada para todos os usuários. Para configurar a descriptografia automática sem criptografia automática, defina bypassAutoEncryption(true).

O exemplo de código é do ClientSideEncryptionExplicitEncryptionOnlyTour.java no Github repositório do do código fonte do driver.

...
MongoClientSettings clientSettings = MongoClientSettings.builder()
.autoEncryptionSettings(AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace.getFullName())
.kmsProviders(kmsProviders)
.bypassAutoEncryption(true)
.build())
.build();
MongoClient mongoClient = MongoClients.create(clientSettings);
...
// Explicitly encrypt a field
BsonBinary encryptedFieldValue = clientEncryption.encrypt(new BsonString("123456789"),
new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
ObservableSubscriber<InsertOneResult> insertOneSubscriber = new OperationSubscriber<>();
collection.insertOne(new Document("encryptedField", encryptedFieldValue))
.subscribe(insertOneSubscriber);
insertOneSubscriber.await();
ObservableSubscriber<Document> documentSubscriber = new OperationSubscriber<>();
collection.find().first().subscribe(documentSubscriber);
Document doc = documentSubscriber.get().get(0);
System.out.println(doc.toJson());

Voltar

Ler operações

Próximo

Operações de Escrita