Hi, I recently started using CSFLE with enterprise edition. We are using the following AutoEncryptionSettings settings to create the client:
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.schemaMap(new HashMap<String, BsonDocument>() {{
put("admin" + "." + "school",
// Need a schema that references the new data key
BsonDocument.parse("{"
+ " properties: {"
+ " student: {"
+ " encrypt: {"
+ " keyId: [{"
+ " \"$binary\": {"
+ " \"base64\": \"" + base64DataKeyId + "\","
+ " \"subType\": \"04\""
+ " }"
+ " }],"
+ " bsonType: \"object\","
+ " algorithm: \"AEAD_AES_256_CBC_HMAC_SHA_512-Random\""
+ " }"
+ " }"
+ " },"
+ " \"bsonType\": \"object\""
+ "}"));
}}).build();
Whenever our App restarts per server, we create a new data encryption key using “clientEncryption.createDataKey(“local”, new DataKeyOptions())” command as we didn’t want to use a single data encryption key(DEK). The output of the above createDataKey command is base64 encoded and pass to the schemaMap as “base64DataKeyId” as shown in above autoEncryptionSettings. Problem is, we inserted data into “school” collection using 3 App servers(that is, we currently created and used 3 DEKs in 3 servers to insert entries) and when we try to fetch all these records using a 4th server, we are getting the following exception:
com.mongodb.MongoException: HMAC validation failure
at com.mongodb.MongoException.fromThrowableNonNull(MongoException.java:83)
at com.mongodb.client.internal.Crypt.fetchKeys(Crypt.java:286)
at com.mongodb.client.internal.Crypt.executeStateMachine(Crypt.java:244)
at com.mongodb.client.internal.Crypt.decrypt(Crypt.java:128)
at com.mongodb.client.internal.CryptConnection.command(CryptConnection.java:121)
at com.mongodb.client.internal.CryptConnection.command(CryptConnection.java:131)
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:345)
at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:336)
at com.mongodb.internal.operation.CommandOperationHelper.executeCommandWithConnection(CommandOperationHelper.java:222)
at com.mongodb.internal.operation.FindOperation$1.call(FindOperation.java:658)
at com.mongodb.internal.operation.FindOperation$1.call(FindOperation.java:652)
at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:583)
at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:652)
at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:80)
at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:170)
at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:135)
at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:92)
at com.mongodb.client.internal.MongoIterableImpl.forEach(MongoIterableImpl.java:121)
at com.mongodb.client.internal.MongoIterableImpl.into(MongoIterableImpl.java:130)
at Test.main(Test.java:165)
Caused by: com.mongodb.crypt.capi.MongoCryptException: HMAC validation failure
at com.mongodb.crypt.capi.MongoCryptContextImpl.throwExceptionFromStatus(MongoCryptContextImpl.java:145)
at com.mongodb.crypt.capi.MongoCryptContextImpl.throwExceptionFromStatus(MongoCryptContextImpl.java:151)
at com.mongodb.crypt.capi.MongoCryptContextImpl.addMongoOperationResult(MongoCryptContextImpl.java:83)
at com.mongodb.client.internal.Crypt.fetchKeys(Crypt.java:282)
... 18 more
But everything works fine when we use a single DEK across all servers.
So, I would like to understand what could be the issue when using multiple DEKs or if it is recommended to use a single DEK.