Feldbasierte Verschlüsselung in Mongo via Morphium

Info

Datum: 09. 01. 2020 um 22:11:48

Schlagworte: Java

Kategorie: morphium

Ursprünglich veröffentlicht auf: caluga.de

erstellt von Stephan Bösebeck

logged in

ADMIN


Feldbasierte Verschlüsselung in Mongo via Morphium

In der nächsten Version von Morphium wird es ein neues Feature geben: automatische Ver- und Entschlüsselung von Daten.

Dabei wird sicher gestellt, dass die Daten in der Datenbank nur noch verschlüsselt abgelegt bzw. beim lesen entschlüsselt werden. Das funktioniert auch mit Subdokumenten. Technisch werden komplexere Datenstrukturen als JSON encoded und dieser String wird verschlüsselt abgelegt.

Wir haben im Moment support für 2 Arten der Verschlüsselung AES (default) und RSA.

hier der Test für die AES-Verschlüsselung.

´´´ @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;
}

´´´

Dabei gibt es ein paar Klassen, die man kennen sollte:

  • AESEncryptionProvider: das ist eine Implementierung des Interface EncryptionProvider und bietet AES Verschlüsselung an
  • RSAEncryptionProvider: das ist eine Implementierung des Interface EncryptionProvider und bietet RSA Verschlüsselung an
  • alle Verschlüsselungssysteme greifen auf den EncryptionKeyProvider zu, der in der in MorphiumConfig gesetzt werden kann.
    • DefaultEncryptionKeyProvider: man speichert die keys selbst
    • PropertyEncryptionKeyProvider: die keys werden über Properties eingelesen, die keys können selbst wiederum verschlüsselt abgelegt werden (AES verschlüsselung)
    • MongoEncryptionKeyProvider: liest die keys aus der Mongo, Collection und key zur AES-Verschlüsselung können angegeben werden
  • all diese Interfaces können natürlich selbst implementiert werden, falls man gerne noch andere Verschlüsselungsmechanismen nutzen möchte