Crypto Service
Crypto Service provides encryption, decryption, and salted hashing of JSON values for all Wren:IDM components.
- OSGi service class
-
org.forgerock.openidm.crypto.impl.CryptoServiceImpl - OSGi persistent identifier
-
org.forgerock.openidm.crypto - Configuration file
-
none
- Router mapping
-
none
In most cases no configuration is required — sensitive fields in OSGi configuration files and in managed objects are protected automatically.
Direct script use of openidm.encrypt(), openidm.hash(), or openidm.decrypt() is needed only when scripts must inspect or protect values explicitly.
The service depends on KeyStoreService (pid org.forgerock.openidm.keystore) for access to cryptographic keys.
It exposes the CryptoService interface (defined in openidm-util) to all OSGi consumers.
Encryption
Encryption is reversible.
The service encrypts a JsonValue using a symmetric key from the keystore, identified by a caller-supplied alias.
The default cipher is AES/CBC/PKCS5Padding.
The encrypted output is a JSON object with a $crypto wrapper, produced by org.forgerock.json.crypto.JsonCrypto and SimpleEncryptor from the commons-json-crypto library:
{
"$crypto": {
"type": "x-simple-encryption",
"value": {
"cipher": "AES/CBC/PKCS5Padding",
"salt": "<base64>",
"iv": "<base64>",
"data": "<base64>",
"mac": "<base64>",
"key": "openidm-sym-default"
}
}
}
A value is recognised as encrypted when JsonCrypto.isJsonCrypto() returns true for it, which checks for the $crypto wrapper.
Hashing
Hashing is a one-way operation.
The service computes a salted digest of the input value and stores the result as a $crypto blob.
The original value cannot be recovered from the stored form.
Encryption is appropriate when the original value must be recoverable (for example, passwords used in outbound connector authentication); hashing is appropriate when only equality verification is required.
Hash algorithm
A 16-byte cryptographically random salt is generated for each hash operation.
The salt is appended to the plaintext, the combined buffer is hashed, and the result is stored as base64(digest || salt).
When verifying a value, the salt is extracted from the stored blob and the same procedure is repeated on the candidate plaintext.
The following algorithms are supported:
| Algorithm constant | Description |
|---|---|
|
MD5 message digest |
|
SHA-1 message digest |
|
256-bit SHA-2 (default) |
|
384-bit SHA-2 |
|
512-bit SHA-2 |
Configuration File Protection
Wren:IDM automatically encrypts sensitive fields in OSGi configuration files.
Bundle developers declare which fields must be protected by implementing MetaDataProvider; the Crypto Service applies encryption automatically at write time based on that metadata.
For built-in components, this metadata is already provided — no administrator action is needed.
Integrators writing custom OSGi bundles must implement org.forgerock.openidm.metadata.MetaDataProvider (from the openidm-util module) to mark their sensitive fields.
When a configuration is written, ConfigCrypto inspects the metadata and encrypts any plaintext sensitive fields using AES/CBC/PKCS5Padding and the alias specified by the openidm.config.crypto.alias boot property.
The alias and other crypto-related properties are set in conf/boot/boot.properties.
The shipped boot.properties sets openidm.config.crypto.alias to openidm-sym-default; the Java-level fallback (used only if the property is absent) is openidm-config-default.
boot.properties — crypto aliases# Key alias used to encrypt sensitive configuration fields
openidm.config.crypto.alias=openidm-sym-default
# Key alias used for the self-service shared key
openidm.config.crypto.selfservice.sharedkey.alias=openidm-selfservice-key
# Key alias used for JWT session HMAC signing
openidm.config.crypto.jwtsession.hmackey.alias=openidm-jwtsessionhmac-key
Already-encrypted values (those with the $crypto wrapper) are not re-encrypted.
Fields are only encrypted when their stored form is plaintext.
|
Managed Object Field Protection
Individual fields in a managed object schema can be marked for automatic encryption or hashing.
The protection is applied in the onStore lifecycle hook before writing to the repository, and is idempotent — already-protected values are not processed again.
Field encryption
Add an encryption object to the field definition in managed.json.
The key property is required; cipher is optional and defaults to AES/CBC/PKCS5Padding.
| Property | Required | Description |
|---|---|---|
|
yes |
Keystore alias identifying the symmetric key to use |
|
no |
JCE cipher string; defaults to |
The default managed.json uses this for the password field of the user object:
managed.json — password field encryption"password": {
"type": "string",
"encryption": {
"key": "openidm-sym-default"
}
}
Encrypted fields are returned as $crypto blobs when the object is read; decryption is not applied automatically on retrieval.
To access the plaintext value from a script, call openidm.decrypt() on the returned blob, for example:
|
var plain = openidm.decrypt(object.password);
Script API
The Crypto Service is exposed to scripts through the openidm binding.
The following functions are available when the Crypto Service is active.
For guidance on when to use hashing versus encryption, see Hashing.
| Function | Description |
|---|---|
|
Encrypts |
|
Decrypts a |
|
Hashes |
|
Returns |
|
Returns |
|
Returns |
openidm.isEncrypted returns true for any $crypto wrapper, including hashed values.
Use openidm.isHashed to test specifically for a salted hash.
|
All functions except hash are removed from the openidm binding in unbindCryptoService when the Crypto Service becomes inactive.
hash remains available because CryptoServiceImpl.hash() uses only MessageDigest-based FieldStorageScheme implementations and requires no keystore access; it continues to operate via the retained service reference even after unbind.