Search code examples
javamongodbspring-data-mongodbjava-17mongodb-csfle

MongoDB Automatic client side Field level Encryption | mongoCryptD daemon not marking the fields to be encrypted


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.

Edit 2:

So we found that the issue was related to the schemaMap. The key name in the schemaMap was not matching with the document name. The mongo document name was "myDocument" and what I put in the key of schemaMap was "MyDocument" with "M" in caps, thus it was not able to find the proper mapping and was failing.


Solution

  • 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.