fieldbased encryption in mongo using Morphium

published : 2020-01-09 changed: 2020-01-10

category: Computer --> programming --> MongoDB --> morphium

tags: java


There will be a new feature in the next version of Morphium: automatic encryption and decryption of data.

This ensures that the data is only stored in encrypted form in the database or is decrypted when it is read. This also works with sub-documents. Technically, more complex data structures than JSON are encoded and this string is stored encrypted.

We currently have support for 2 types of encryption AES (default) and RSA.

here is the test for AES encryption.

    @Test
    public void objectMapperTest() throws Exception {
        morphium.getEncryptionKeyProvider().setEncryptionKey("key", "1234567890abcdef".getBytes());
        morphium.getEncryptionKeyProvider().setDecryptionKey("key", "1234567890abcdef".getBytes());
        MorphiumObjectMapper om = morphium.getMapper();
        EncryptedEntity ent = new EncryptedEntity();
        ent.enc = "Text to be encrypted";
        ent.text = "plain text";
        ent.intValue = 42;
        ent.floatValue = 42.3f;
        ent.listOfStrings = new ArrayList<>();
        ent.listOfStrings.add("Test1");
        ent.listOfStrings.add("Test2");
        ent.listOfStrings.add("Test3");

        ent.sub = new Subdoc();
        ent.sub.intVal = 42;
        ent.sub.strVal = "42";
        ent.sub.name = "name of the document";

        Map<String, Object> serialized = om.serialize(ent);
        assert (!ent.enc.equals(serialized.get("enc")));

        EncryptedEntity deserialized = om.deserialize(EncryptedEntity.class, serialized);
        assert (deserialized.enc.equals(ent.enc));
        assert (ent.intValue.equals(deserialized.intValue));
        assert (ent.floatValue.equals(deserialized.floatValue));
        assert (ent.listOfStrings.equals(deserialized.listOfStrings));
    }


    @Entity
    public static class EncryptedEntity {
        @Id
        public MorphiumId id;

        @Encrypted(provider = AESEncryptionProvider.class, keyName = "key")
        public String enc;

        @Encrypted(provider = AESEncryptionProvider.class, keyName = "key")
        public Integer intValue;

        @Encrypted(provider = AESEncryptionProvider.class, keyName = "key")
        public Float floatValue;

        @Encrypted(provider = AESEncryptionProvider.class, keyName = "key")
        public List<String> listOfStrings;

        @Encrypted(provider = AESEncryptionProvider.class, keyName = "key")
        public Subdoc sub;


        public String text;
    }


    @Embedded
    public static class Subdoc {
        public String name;
        public String strVal;
        public Integer intVal;
    }

There are a few classes you should know:

  • AESEncryptionProvider: this is an implementation of the interfaceEncryptionProvider and offers AES encryption
  • RSAEncryptionProvider: this is an implementation of the interfaceEncryptionProvider and offers RSA encryption
  • All encryption systems access the EncryptionKeyProvider, which can be set in the MorphiumConfig.
    • DefaultEncryptionKeyProvider: you save the keys yourself
    • PropertyEncryptionKeyProvider: the keys are read in via properties, the keys themselves can be stored in encrypted form (AES encryption)
    • MongoEncryptionKeyProvider: reads the keys from the Mongo, Collection and encryption key can be specified
  • Of course, all of these interfaces can be implemented yourself.

created Stephan Bösebeck (stephan)