October 20th, Q&A session: Get you issues solved and questions answered!

GitHub logo
Edit

Transparent Data Encryption

Warning
This feature is in beta and not recommended for use in production environments.

Overview

Transparent data encryption (TDE) allows users to encrypt their data at rest.

When Ignite persistence is turned on, encryption can be enabled per cache/table, in which case the following data will be encrypted:

  • Data on disk

  • WAL records

If you enable cache/table encryption, Ignite will generate a key (called cache encryption key) and will use this key to encrypt/decrypt the data in the cache. The cache encryption key is held in the system cache and cannot be accessed by users. When the cache encryption key is sent to other nodes or saved to disk (when the node goes down), it is encrypted using the master key. The master key must be specified by the user in the configuration.

The same master key must be specified via the configuration in every server node. One way to ensure you’re using the same key is to copy the JKS file from one node to the other nodes. If you try to enable TDE using different keys, the nodes with the different key will not be able to join the cluster (will be rejected based on differing digests).

Ignite uses JDK-provided encryption algorithms: "AES/CBC/PKCS5Padding" to encrypt WAL records and "AES/CBC/NoPadding" to encrypt data pages on disk. To learn more about implementation details, see KeystoreEncryptionSpi.

Limitations

Transparent Data Encryption has some limitations that you should be aware of before deploying it in your production environment.

Encryption

  • No option to change the encryption key at runtime.

  • No option to encrypt/decrypt existing caches/tables.

Snapshots and Recovery

  • No support for snapshots. Snapshots are not encrypted and it’s not possible to recover from a snapshot that includes an encrypted table or cache.

Configuration

To enable encryption in the cluster, provide a master key in the configuration of each server node. A configuration example is shown below.

<bean class="org.apache.ignite.configuration.IgniteConfiguration">
    <!-- We need to configure EncryptionSpi to enable encryption feature. -->
    <property name="encryptionSpi">
        <!-- Using EncryptionSpi implementation based on java keystore. -->
        <bean class="org.apache.ignite.spi.encryption.keystore.KeystoreEncryptionSpi">
            <!-- Path to the keystore file. -->
            <property name="keyStorePath" value="ignite_keystore.jks"/>
            <!-- Password for keystore file. -->
            <property name="keyStorePassword" value="mypassw0rd"/>
            <!-- Name of the key in keystore to be used as a master key. -->
            <property name="masterKeyName" value="ignite.master.key"/>
            <!-- Size of the cache encryption keys in bits. Can be 128, 192, or 256 bits.-->
            <property name="keySize" value="256"/>
        </bean>
    </property>
    <property name="cacheConfiguration">
        <bean class="org.apache.ignite.configuration.CacheConfiguration">
            <property name="name" value="encrypted-cache"/>
            <property name="encryptionEnabled" value="true"/>
        </bean>
    </property>

</bean>
IgniteConfiguration cfg = new IgniteConfiguration();

KeystoreEncryptionSpi encSpi = new KeystoreEncryptionSpi();

encSpi.setKeyStorePath("/home/user/ignite-keystore.jks");
encSpi.setKeyStorePassword("secret".toCharArray());

cfg.setEncryptionSpi(encSpi);
This API is not presently available for C++. You can use XML configuration.

When the master key is configured, you can enable encryption for a cache as follows:

<property name="cacheConfiguration">
    <bean class="org.apache.ignite.configuration.CacheConfiguration">
        <property name="name" value="encrypted-cache"/>
        <property name="encryptionEnabled" value="true"/>
    </bean>
</property>
CacheConfiguration<Long, String> ccfg = new CacheConfiguration<Long, String>("encrypted-cache");

ccfg.setEncryptionEnabled(true);

ignite.createCache(ccfg);
CREATE TABLE encrypted(
  ID BIGINT,
  NAME VARCHAR(10),
  PRIMARY KEY (ID))
WITH "ENCRYPTED=true";

Master Key Generation Example

A keystore with a master key can be created using keytool as follows:

Master Key Generation Example
user:~/tmp:[]$ java -version
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)

user:~/tmp:[]$ keytool -genseckey \
-alias ignite.master.key \
-keystore ./ignite_keystore.jks \
-storetype PKCS12 \
-keyalg aes \
-storepass mypassw0rd \
-keysize 256

user:~/tmp:[]$ keytool \
-storepass mypassw0rd \
-storetype PKCS12 \
-keystore ./ignite_keystore.jks \
-list

Keystore type: PKCS12
Keystore provider: SunJSSE

Your keystore contains 1 entry

ignite.master.key, 07.11.2018, SecretKeyEntry,

Source Code Example