Client Side Encryption schema error with MongoDB driver 4.3+
See original GitHub issueHi,
there seems to be an incompatibility with the generated validation schema with encrypted properties and newer driver versions.
I have the following entity class, and use MongoJsonSchemaCreator
to create the schema:
@Document( collection = "blockedEmails" )
@Encrypted( keyId = "#{ mongocrypt.keyId(#target) }", algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic )
public class EmailBlocklistEntryEntity {
@Encrypted
private String email;
public String getEmail() {
return email;
}
public void setEmail( String email ) {
this.email = email;
}
}
This creates the following schema:
{"encryptMetadata": {"keyId": [{"$binary": {"base64": "9MNyAMBdQFWAQ6IKUAt9Mw==", "subType": "04"}}], "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"}, "type": "object", "properties": {"email": {"encrypt": {"bsonType": "string", "algorithm": null}}}}
With driver version 4.3.4 and newer (didn’t test 4.3.0-4.3.3), when creating a collection with this schema, I receive the following exception:
Caused by: org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 51084 (Location51084): 'Array elements must have bindata type UUID, found 3' on server nxpv-squad2-test-shard-00-02.c80ou.azure.mongodb.net:27017. The full response is {"ok": 0.0, "errmsg": "Array elements must have bindata type UUID, found 3", "code": 51084, "codeName": "Location51084", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1641832661, "i": 1}}, "signature": {"hash": {"$binary": {"base64": "jZXcnJl4LpShCTnYIabMjNP9PDg=", "subType": "00"}}, "keyId": 7017886637933723649}}, "operationTime": {"$timestamp": {"t": 1641832661, "i": 1}}}; nested exception is com.mongodb.MongoCommandException: Command failed with error 51084 (Location51084): 'Array elements must have bindata type UUID, found 3' on server nxpv-squad2-test-shard-00-02.c80ou.azure.mongodb.net:27017. The full response is {"ok": 0.0, "errmsg": "Array elements must have bindata type UUID, found 3", "code": 51084, "codeName": "Location51084", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1641832661, "i": 1}}, "signature": {"hash": {"$binary": {"base64": "jZXcnJl4LpShCTnYIabMjNP9PDg=", "subType": "00"}}, "keyId": 7017886637933723649}}, "operationTime": {"$timestamp": {"t": 1641832661, "i": 1}}}
at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:140)
at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2906)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:530)
at org.springframework.data.mongodb.core.MongoTemplate.doCreateCollection(MongoTemplate.java:2405)
at org.springframework.data.mongodb.core.MongoTemplate.createCollection(MongoTemplate.java:619)
With driver version 4.2.3 it works.
I’m not sure whether this is to be considered a bug in newer driver versions, or an incompatible but intended change that Spring Data MongoDB needs to adapt to. I’m using Spring Data MongoDB 3.3.0 in a Spring Boot 2.6.2 application.
I’m not familiar with the MongoDB driver code base but when looking through issues implemented in 4.3.x I came across this one that I assume could be related: https://jira.mongodb.org/browse/JAVA-4140
This occurs with MongoDB Atlas versions 4.4 and 5.0.
Issue Analytics
- State:
- Created 2 years ago
- Comments:9 (5 by maintainers)
I can reproduce the issue, using the provided sample application. Here’s what’s happening:
org.springframework.boot.autoconfigure.mongo.MongoPropertiesClientSettingsBuilderCustomizer
asJAVA_LEGACY
, which means that all instances ofjava.util.UUID
will be encoded as BSON Binary subtype 3org.springframework.data.mongodb.util.encryption.EncryptionUtils#resolveKeyId
as an instance ofjava.util.UUID
.java.util.UUID
into the JSON schema document (of typeorg.bson.Document
) that is passed as the validator when creating the collection.@rainerfrey-inxmail to work around the issue, I suggest that you tack on
uuidRepresentation=standard
to the uri, e.g.mongodb://localhost/?uuidRepresentation=standard
. But only do this if you’re not already relying on UUID encoding in any other parts of your application (i.e. none of your collections are already storing UUID values).For the Spring team, I suggest that
org.springframework.data.mongodb.util.encryption.EncryptionUtils#resolveKeyId
be changed such that it returns an instance oforg.bson.types.Binary
rather thanjava.util.UUID
. Note that the catch clause in that method will already do that:Assuming that’s feasible, it will avoid the UUID encoding issue entirely.
I can confirm that setting the uuid representation to standard solves the issue with driver 4.4.0.