Confidential storage

To save sensitive data, the interface ConfidentialStorage has been created in the application. To read the data from the storage, it is necessary to know its owner (entity), and the key.

The storage is currently used for:

  • saving the identity password
  • saving the sensitive data in dynamic forms (which are used also for connectors configuration, etc.)
  • saving sensitive configuration items (coming soon)

After reading, the value should flow through the application in the form of GuardedString, if possible. This is definitely true for the string values (password, tokens), nevertheless, the confidential storage supports saving of any serializable type of data (GuardedString is not serializable by definition, so the storage explicitly exposes methods for GuardedString).

The current implementation of the confidential storage saves data into a separate database chart (owner, key, value). The next expected implementation counts with the use of Vault as the key-value of the storage ⇒ The owner will be part of the key.

The storage is encrypted by key that is saved in the application property cipher.crypt.secret.key or in a file which is set in the application property cipher.crypt.secret.keyPath.

For crypt confidential storage is used algorithm AES/CBC/PKCS5Padding (more info) for this algorithm is necessary 128 bits key ~ 16 characters (key must be exactly 128 bits!!). For generate key you can use this:

cat /dev/urandom | tr -dc 'a-z0-9' | head -c 16
In default installation CzechIdM doesn't contain any key. Please set some key for crypt confidential storage before run your application in production mode.
In production mode is possible change key for crypt (encode/decode) values in confidential storage. For this purpose was created new LRT (ChangeConfidentialStorageKey). LRT must be started after you change confidential storage key to new. As parameter will be given old key.
Search key order:
  1. The highest priority has value in property 'cipher.crypt.secret.key'.
  2. Second is file with key on the path in property 'cipher.crypt.secret.keyPath'.

Example settings:

cipher.crypt.secret.key=someSuperSecretKey

or

cipher.crypt.secret.keyPath=/path/to/key/file

Key can be change during production mode by long running task ChangeConfidentialStorageKey. This task must be started after you changed key to newer. As parameter will be given old key for confidential storage.