Skip to content

Support property-based explicit field encryption #4284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
christophstrobl opened this issue Feb 1, 2023 · 0 comments
Closed

Support property-based explicit field encryption #4284

christophstrobl opened this issue Feb 1, 2023 · 0 comments
Assignees
Labels
type: enhancement A general enhancement

Comments

@christophstrobl
Copy link
Member

christophstrobl commented Feb 1, 2023

Extend the property based conversion feature to combine @Encrypted with @ValueConverter into a single annotation that is evaluated when mapping domain types into their store native representation and back.

@Encrypted
@ValueConverter(MongoCryptConverter.class)
@interface EncryptedField {

        @AliasFor(annotation = ValueConverter.class, value = "value")
        Class<? extends PropertyValueConverter> converter() default MongoCryptConverter.class;

	@AliasFor(annotation = Encrypted.class, value = "algorithm")
	String algorithm() default "";

	String altKeyName() default "";
}

The annotation can be applied on a per property basis covering simple values (like String, Integer) as well as complex ones (like an Address) or entire collections of values as outlined below.

@Document
public class Person {

	String id;
	String name;

	@EncryptedField(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic) 
	String ssn;

	@EncryptedField(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random, altKeyName = "secret-key")
	String wallet;

	@EncryptedField(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random)
	Address address;

	@EncryptedField(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random)
	List<Address> listOfComplex;

	// use the value stored in Person.name as value for the altKeyName attribute
	@EncryptedField(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random, altKeyName = "/name")
	String viaAltKeyNameField;

	// ...
}

The EncryptingConverter SPI offers dedicated methods to en-/decrypt objects using an EncryptionContext that provides access to the underlying encryption engine plus all the additional information derived from the target property itself.

interface EncryptingConverter extends MongoValueConverter<Object, Object> {

	@Override
	default Object read(Object value, MongoConversionContext context) {
	    return decrypt(value, buildEncryptionContext(context));
	}	

	@Override
	default BsonBinary write(Object value, MongoConversionContext context) {
		return encrypt(value, buildEncryptionContext(context));
	}

	Object decrypt(Object value, MongoEncryptionContext context);

	BsonBinary encrypt(Object value, MongoEncryptionContext context)
	
	MongoEncryptionContext buildEncryptionContext(MongoConversionContext context);
}

The default implementation (MongoCryptConverter implements EncryptingConverter) will be using com.mongodb.client.vault.ClientEncryption for en-/decrypt operations and is set as default for @EncryptedField(converter).

To use explicit encryption in a reactive setup one can choose to use the imperative converter (still using the sync mongodb encryption library) within the reactive flow or switch the default converter to a fully reactive variant (using the drivers reactive streams API) resolving values on subscribe.

interface ReactiveEncryptingConverter extends MongoValueConverter<Object, Object> {

	@Override
	default Object read(Object value, MongoConversionContext context) {
	    return decrypt(value, buildEncryptionContext(context));
	}	

	@Override
	default BsonBinary write(Object value, MongoConversionContext context) {
		return encrypt(value, buildEncryptionContext(context));
	}

	Mono<Object> decrypt(Object value, MongoEncryptionContext context);

	Mono<BsonBinary> encrypt(Object value, MongoEncryptionContext context)

	ManualEncryptionContext buildEncryptionContext(MongoConversionContext context);
}
@christophstrobl christophstrobl added the type: enhancement A general enhancement label Feb 1, 2023
@christophstrobl christophstrobl self-assigned this Feb 1, 2023
@mp911de mp911de changed the title Support property based explicit field encryption Support property-based explicit field encryption Mar 14, 2023
@mp911de mp911de added this to the 4.1 M3 (2023.0.0) milestone Mar 14, 2023
mp911de added a commit that referenced this issue Mar 15, 2023
Remove caching variant of MongoClientEncryption. Rename types for consistent key alt name scheme. Rename annotation to ExplicitEncrypted.

Add package-info. Improve documentation wording. Reduce visibility of KeyId and KeyAltName to package-private.

Original pull request: #4302
See: #4284
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants