skip to Main Content

I am using MongoDB’s automatic client side field level encryption, But I observed that the fields are not getting encrypted in the collection.

  • The MongoDB-crypt library that I am using is 1.6.1
  • mongo driver core and sync version are 4.9.1
  • The MongoCryptD version is 5.0.3
  • The OS is linux (RHEL 7.9)
  • MongoDB version 4.2.11 Enterprise edition.
  • Java JDK- 17

The Class that represents my document that I want to perform field encryption on is annotated with @Encrypted annotation with the data key ID and the Encryption algorithm
and also the fields in that class I want to encrypt is simply annotated with @Encypted annotation.

So it looks something like this ->

@Data  // lombok
@Document
@Encrypted (keyID="<the key id>", algorithm= "<The algorithm>")
public class MyDocument{
   @Id
   private UUID dataID;

   @Encrypted
   private String fieldToBeEncrypted;
   
   private String otherField;
} 

I am using MongoJsonSchemaCreator’s createSchemaFor() method with a filter method MongoJsonSchemaCreator.encryptedOnly() in order to generate a Json Schema after which I then create a SchemaMap from.

this schemaMap I am then populating while creating AutoEncryptionSettings.->

MongoClientSettings clientSettings = MongoClientSettings.builder()
.autoEncryptionSettings(AutoEncryptionSettings.builder()
        .keyVaultNamespace(keyVaultNamespace)
        .kmsProviders(kmsProviders)
        .schemaMap(schemaMap)
        .extraOptions(extraOptions)
        .build())
...(other settings)
    .build();

The master key that I am putting in the kmsProviders is a 96 bytes random character that I generate with OpenSSL random command.


Now the problem is that I am not seeing any data being encrypted and also I do not see any failure message in the console logs.

Now my question is ->

  1. Where does the actual encryption happens ? it is definitly not in the mongocryptd as the docs states so.
    So what is actually handling the encryption ?
  2. Is there any settings we have to enable in the mongo cluster in order to enable auto field encryption.
  3. The versions that I have stated at the top of my question are those inter compatible with each other and the linux OS as well ?
  4. Is there any checklist in general that I can use in order to troubleshoot this issue of encryption not happening ?

It seems that the mongocryptd process is not marking the fields to be encrypted for writes and thus no encryption is taking place but not sure


Edit 1:

Sharing the rough SchemaMap that I tried in my AutoEncryptionSettings but this to has failed ->

schemaMap.put(getDatabaseName() + ".MyDocument", BsonDocument.parse("{"
  + "  bsonType: "object","
  + "  encryptMetadata: {"
  + "    keyId: [UUID("" + keyUuid + "")]"
  + "  },"
  + "  properties: {"
  + "    fieldToBeEncrypted: {"
  + "      encrypt: {"
  + "        bsonType: "string","
  + "        algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic""
  + "      }"
  + "    }"
  + "  }"
  + "}"));

Here the "keyUuid" is the UUID of the datakey that was generated with ClientEncryption class’s createDataKey() method. I had commented the @Encrypted annotation on MyDocument class temporarily in order to pass this hard coded SchemaMap.

2

Answers


  1. Chosen as BEST ANSWER

    I am putting the code that generates the schemaMap below ->

    private Map<String, BsonDocument> generateSchemaMap() {
        MongoJsonSchemaCreator schemaCreator = MongoJsonSchemaCreator.create(mappingContext);
        Map<String, BsonDocument> schemaMap = new HashMap<>();
        Class encryptedEntityClass = MyDocument.class ;  //Class that has fields to be encrypted -> MyDocument
        MongoJsonSchema schema = schemaCreator
                .filter(MongoJsonSchemaCreator.encryptedOnly); // this checks for entity marked with @Encrypted annotation only.
                .createSchemaFor(encryptedEntityClass);
        
        schemaMap.put("dbName.MyDocument", 
                schema.schemaDocument().toBsonDocument(encryptedEntityClass,
                     MongoClientSettings.getDefaultCodecRegistry()));
        return schemaMap;
            
    }
    
    

    this SchemaMap then I put inside my AutoEncryptionSettings ->

    MongoClientSettings.Builder.autoEncryptionSettings(
              AutoEncryptionSettings.builder()
                .keyVaultNamespace(encryptionConfig.getKeyVaultNamespace())
                .kmsProviders(LocalKmsUtils.providersMap(encryptionConfig.getMasterKeyPath()))
                .schemaMap(generateSchemaMap())
              .build())
             .build();
    

  2. Writing it as answer since it’s quite big:

    1. Where does the actual encryption happens ? – inside java driver (in particular inside a libmongocrypt library), but mongocryptd is also required daemon for this workflow.
    2. Is there any settings we have to enable in the mongo cluster in order to enable auto field encryption. – there are options to disable encrypting, but by default it should work as long as you specified correct schemaMap.
    3. are those inter compatible with each other – it should, but even if no, such simple functionality were in csfle logic from the beginning.
    4. Where is @Encrypted attribute came from, I’m not java developer, but I didn’t find it in documentation. See articles how it should be configured here. Also, in order to troubleshot further, provide schemaMap value you add to the clientSettings.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search