Chapter 25. Crypto extension

Table of Contents

Description
Including in a project
Usage

Description

Crypto module allows encrypt and decrypt values stored in DB transparently to your Java app.

Including in a project

Maven

<dependency>
    <groupId>org.apache.cayenne</groupId>
    <artifactId>cayenne-crypto</artifactId>
    <version>4.1.M1</version>
</dependency>

Gradle

compile 'org.apache.cayenne:cayenne-crypto:4.1.M1'

Usage

Setup your model and DB

To use crypto module you must prepare your database to allow byte[] storage and properly name columns that will contain encrypted values.

Currently supported SQL types that can be used to store encrypted data are:

  1. Binary types: BINARY, BLOB, VARBINARY, LONGVARBINARY. These types are preferred.

  2. Character types, that will store base64 encoded value: CHAR, NCHAR, CLOB, NCLOB, LONGVARCHAR, LONGNVARCHAR, VARCHAR, NVARCHAR

Note

Not all data types may be supported by your database.

Default naming strategy that doesn't require additional setup suggests using "CRYPTO_" prefix. You can change this default strategy by injecting you own implementation of org.apache.cayenne.crypto.map.ColumnMapper interface.

ServerRuntime.builder()
        .addModule(CryptoModule.extend()
                .columnMapper(MyColumnMapper.class)
                .module())

Here is an example of how ObjEntity with two encrypted and two unencrypted properties can look like:

Setup keystore

To perform encryption you must provide KEYSTORE_URL and KEY_PASSWORD. Currently crypto module supports only Java "jceks" KeyStore.

ServerRuntime.builder()
        .addModule(CryptoModule.extend()
                .keyStore(this.getClass().getResource("keystore.jcek"), "my-password".toCharArray(), "my-key-alias")
                .module())

Additional settings

Additionally to ColumnMapper mentioned above you can customize other parts of crypto module. You can enable gzip compression and HMAC usage (later will ensure integrity of data).

ServerRuntime.builder()
        .addModule(CryptoModule.extend()
                .compress()
                .useHMAC()
                .module())

Another useful extension point is support for custom Java value types. To add support for your data type you need to implement org.apache.cayenne.crypto.transformer.value.BytesConverter interface that will convert required type to and from byte[].

ServerRuntime.builder()
        .addModule(CryptoModule.extend()
                .objectToBytesConverter(MyClass.class, new MyClassBytesConverter())
                .module())

Note

In addition to Java primitive types (and their object counterparts), crypto module supports encryption only of java.util.Date, java.math.BigInteger and java.math.BigDecimal types.