Confidential storage
To save sensitive data, a confidential storage solution has been created in the application. To read the data from this storage, one needs to know its owner (entity), and the key.
The storage is currently used for:
- saving the sensitive data in dynamic forms (EAV) (which are used also for connectors configuration - mainly passwords, etc.)
- saving sensitive configuration items
- temporary saving the identity password (when it's provisioned to an end system)
The current implementation of the confidential storage saves data into a separate database chart (owner, key, value).
The cipher and the secret key
The storage is encrypted by the 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.
Example settings:
cipher.crypt.secret.key=someSuperSecretKey
or
cipher.crypt.secret.keyPath=/path/to/key/file
Search key order:
- The highest priority has value in property 'cipher.crypt.secret.key'.
- Second is file with key on the path in property 'cipher.crypt.secret.keyPath'.
IdM uses the algorithm AES/CBC/PKCS5Padding (more info) for encryption of the confidential storage values. The algorithm operates with 128bit or 256bit key (key must be only 128 or 256 bits!!). To generate the key, you can use one of these commands:
cat /dev/urandom | tr -dc 'a-z0-9' | head -c 16 cat /dev/urandom | tr -dc 'a-z0-9' | head -c 32
Change the confidential storage key
The storage key can be changed during production mode by long running task Change confidential storage key (ChangeConfidentialStorageKey). This task must be started after you changed key to newer and restarted IdM for the change to take place. Use the old key for the confidential storage as a parameter of this task.
This task should be used only for changing the key, i.e. you will never use the old value again for encrypting the confidential storage. Typically, when your secret key was compromised, or you want to use a longer key to increase security. The reason is that the old key is saved in the history of the all long running tasks, so it's no longer a secret after you use it this way.
Note that after you change the confidential storage key with this task, all your current backups of the IdM database can't (or shouldn't) be used any longer for a full recovery in case of some failure. They contain values encrypted with the old key, which is no longer secret. So it's recommended to change the confidential storage key only as a separate action in a stable IdM environment, not as a part of some other (potentially breaking) changes in the production environment.
To sum up the steps required to change the confidential storage key:
- Backup the IdM database.
- Backup the original confidential storage key (the file specified by the property ``cipher.crypt.secret.keyPath`` or directly in the property ``cipher.crypt.secret.key``, both would be in the ``application-xxx.properties`` file on the server with IdM).
- Generate a new confidential storage key and save it to the file or the configuration property.
- Restart IdM.
- Schedule the task Change confidential storage key (ChangeConfidentialStorageKey) in IdM, set the original key to the parameter old key, and run the task.
- Check the processed items of the task for any failures.
- Backup the IdM database.
- As the old encryption key is now considered "not secret", you have to take care of historical IdM database backups. Those backups could potentially leak sometime in the past and now they could become decryptable since the historical encryption key is no longer kept secret. Follow your company guidelines on destroying secret information.
Generate initialization vectors
The long running task Generate initialization vectors for the confidential storage (GenerateConfidentialStorageInitializationVectorsTaskExecutor, available since 10.8) should be used when upgrading from CzechIdM versions older than 10.6 to a newer version. The reason is improved security - avoiding potential cryptography attacks on the data saved in the confidential storage by older versions of the application, which used a static initialization vector.
Recommended steps:
- Backup the IdM database.
- Schedule the task Generate initialization vectors for the confidential storage in IdM and run the task.
- Check the processed items of the task for any failures.
Note: When the tasks runs after the upgrade, you could notice the following warnings in IdM logs: IdM use old behavior with static vector. Please don't use this deprecated method.
This is expected. After the task ends, you should never see this warning again.