MongoDB Client Side Field Level Encryption using Java-Spring: Part 2 Community Edition (Manual Encryption)

Minimum Requirements

Github Project

Dependencies

Generating Customer Master key(CMK)

$(echo "$(head -c 96 /dev/urandom | base64 | tr -d '\n')")

Location of Master Key

Generating Data Encryption Key (DEK)

BsonBinary createDataKey(String kmsProvider, DataKeyOptions dataKeyOptions);
String connectionString = "mongodb://localhost:27017";
String keyVaultNamespace = "encryption.__keyVault";
//Client Encryption Settings...
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.build())
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
//ClientEncryption Object
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
BsonBinary dataKeyId = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions());
System.out.println("DataKeyId [UUID]: " + dataKeyId.asUuid());

String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData());
System.out.println("DataKeyId [base64]: " + base64DataKeyId);

DEK in the database

@Override
public MongoClient mongoClient() {
kmsHandler.buildOrValidateVault();
MongoClient mongoClient = new MongoClientImpl(getMongoClientSettings(),getMongoDriverInfo());
return mongoClient;
}

Encrypting ,Decrypting and Searching Data

Encrypting Data

public EncryptedPerson getEncrypedPerson(Person p) {

EncryptedPerson ep = new EncryptedPerson(p.getFirstName(),p.getLastName());
ep.setSsn(kmsHandler.getClientEncryption().encrypt(new BsonInt32(p.getSsn()),getEncryptOptions(DETERMINISTIC_ENCRYPTION_TYPE)));
ep.setPhone(kmsHandler.getClientEncryption().encrypt(new BsonString(p.getPhone()),getEncryptOptions(RANDOM_ENCRYPTION_TYPE)));
ep.setBloodType(kmsHandler.getClientEncryption().encrypt(new BsonString(p.getBloodType()),getEncryptOptions(RANDOM_ENCRYPTION_TYPE)));
return ep;
}

Decrypting Data

public Person getPerson(EncryptedPerson ep){

Person p = new Person(ep.getFirstName(),ep.getLastName());
p.setSsn(kmsHandler.getClientEncryption().decrypt(ep.getSsn()).asNumber().intValue());
p.setPhone(kmsHandler.getClientEncryption().decrypt(ep.getPhone()).asString().getValue());
p.setBloodType(kmsHandler.getClientEncryption().decrypt(ep.getBloodType()).asString().getValue());
return p;

}

Converters

Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.bson.types.Binary] to type [org.bson.BsonBinary]
/**
* Returns the list of custom converters that will be used by the MongoDB template
*
**/
public CustomConversions customConversions() {
CustomConversions customConversions = new MongoCustomConversions(
Arrays.asList(new BinaryToBsonBinaryConverter(),
new BsonBinaryToBinaryConverter()));
return customConversions;
}
public class BinaryToBsonBinaryConverter implements Converter<Binary, BsonBinary> {
@Override
public BsonBinary convert(Binary source) {
return new BsonBinary(source.getData());
}
}

Searching by Encrypted Field

public BsonBinary getEncryptedSsn(int ssn){
return kmsHandler.getClientEncryption().encrypt(new BsonInt32(ssn),getEncryptOptions(DETERMINISTIC_ENCRYPTION_TYPE));
}
public EncryptedPerson findBySsn(BsonBinary ssn);

Code Workflow

References

--

--

--

Developer, Solution Lead @Paychex. Always look for opportunities to innovate and explore. Twitter: @visweshwar.LinkedIn: visweshwar-ganesh-5797405

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to create a Singleton Firebase-Service in Flutter

MERN STACK DEVELOPMENT

Python Web Scraping Part: 3

Why KubeSphere is Prefer for Development

Road TO Dev — Create a start mechanic

Let’s beat power and area with Arduino Pro Mini

Road TO Dev — Let’s restart!

enum in Java : the only article you need!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Visweshwar Ganesh

Visweshwar Ganesh

Developer, Solution Lead @Paychex. Always look for opportunities to innovate and explore. Twitter: @visweshwar.LinkedIn: visweshwar-ganesh-5797405

More from Medium

Making Real-Time Apps.

Java-Spring Boot | GraphQL | Docker

Spring Boot Microservice with Hazelcast In-Memory Cluster

Deploying Spring Boot App to AWS using CircleCI — Complete guide