How To

How do I synchronize hashed passwords from IDM/OpenIDM (All versions) to DS/OpenDJ (All versions)?

Last updated Nov 2, 2020

The purpose of this article is to provide information on how to pass pre-hashed passwords values within IDM/OpenIDM to DS/OpenDJ.

Background information

The synchronization model for IDM/OpenIDM is to take the encrypted password from its own store, decrypt it and pass it in plain text to DS/OpenDJ for it to hash and store. IDM/OpenIDM also has the capability to hash passwords not just encrypt them. The way in which the passwords are synchronized will differ depending on whether they are encrypted or hashed:


The password is decrypted on the IDM/OpenIDM side using a transform script (defined in sync.json) and then pushed to DS/OpenDJ as plain text. Upon arrival, DS/OpenDJ encrypts or hashes the password.


The hashed password is pushed directly to DS/OpenDJ since hashes are one way and cannot be decrypted before synchronization. If you are hashing within IDM/OpenIDM, the SHA256 algorithm uses a 16 byte Salt value whereas hashing within DS/OpenDJ natively uses a 16 or 8 byte Salt value depending on version (How does DS/OpenDJ (All versions) store password values?). Although hashing might be different between the systems, DS/OpenDJ can still authenticate users whose hashed password has been received from IDM/OpenIDM because DS/OpenDJ can handle varying salt lengths during authentication. The following section details how to identify the Salt value needed for storing and synchronizing hashed passwords.


If you want to synchronize hashed passwords the other way, you must use the DS/OpenDJ Password Sync Plugin because hashed passwords cannot be unhashed. Additionally, there is a known issue with policy validation for hashed passwords, which is fixed in IDM 7: OPENIDM-11456 (Skip password policy validation if password is hashed).

Pre-IDM 7: IDM/OpenIDM cannot authenticate users using passwords that have been hashed by DS/OpenDJ because IDM/OpenIDM expects a fixed (hard-coded) salt length, which is not the salt length used by DS/OpenDJ. See Password Synchronization Plugin Guide and OPENIDM-13293 (Request for IDM to allow for hashed passwords with different salt lengths) for further information.

Salt values

IDM/OpenIDM performs hashing using a randomly generated Salt value. You can identify this Salt value, if required, by manipulating the hashed object since the data value consists of the base64 encoded version of the Hashed value concatenated with the Salt value.

This example demonstrates retrieving the Salt value used when performing the hashing function:

  1. The following JavaScript® code hashes the password value (test) and then outputs information to the log file to show the base64 decoded version of the data and the Salt value used: testOutput = openidm.hash("test","SHA-256");"Hash Output: {}", testOutput); var base64 = b64tO = base64.decode(testOutput.$;"Decoded: {}", b64tO); salt = b64tO.slice(32);"Salt: {}", salt);
  2. Example log output; observe that the decoded value (meaning the Salt and the password itself) returns as a byteArray: Aug 10, 2018 2:28:34 PM org.forgerock.script.scope.FunctionFactory$1$3 call INFO: Hash Output: {$crypto={value={algorithm=SHA-256, data=sDSamS5Qqn1BD3ctddaKJlMQ1XO3QiE5D4cq2laOaFBJPpx58E8xbsAnleJ14r9F}, type=salted-hash}} Aug 10, 2018 2:28:34 PM org.forgerock.script.scope.FunctionFactory$1$3 call INFO: Decoded: [-80, 52, -102, -103, 46, 80, -86, 125, 65, 15, 119, 45, 117, -42, -118, 38, 83, 16, -43, 115, -73, 66, 33, 57, 15, -121, 42, -38, 86, -114, 104, 80, 73, 62, -100, 121, -16, 79, 49, 110, -64, 39, -107, -30, 117, -30, -65, 69] Aug 10, 2018 2:28:34 PM org.forgerock.script.scope.FunctionFactory$1$3 call INFO: Salt: [73, 62, -100, 121, -16, 79, 49, 110, -64, 39, -107, -30, 117, -30, -65, 69]

Synchronizing hashed passwords

You can use passwords in DS/OpenDJ that have been hashed by IDM/OpenIDM as follows:

  1. Configure DS/OpenDJ to allow pre-encoded passwords for the relevant password policy. You can set this using dsconfig, for example:
    • DS 7 and later: $ ./dsconfig set-password-policy-prop --policy-name "Default Password Policy" --port 4444 --bindDN uid=admin --bindPassword password --advanced --set allow-pre-encoded-passwords:true --usePkcs12TrustStore /path/to/ds/config/keystore --trustStorePasswordFile /path/to/ds/config/ --no-prompt
    • Pre-DS 7: $ ./dsconfig set-password-policy-prop --policy-name "Default Password Policy" --port 4444 --bindDN "cn=Directory Manager" --bindPassword password --advanced --set allow-pre-encoded-passwords:true --trustAll --no-prompt
  2. Configure IDM/OpenIDM to hash passwords as detailed in Security Guide › Encoding Attribute Values by Using Salted Hash Algorithms. This change does not update all existing user passwords. Passwords will only be stored as hashes if they are created or updated after this change.
  3. Update the transformation of the password in the IDM/OpenIDM sync.json file (located in the /path/to/idm/conf directory)​ to use the base64 encoded hash and append the appropriate hashing algorithm as a prefix. For example, if you are using the SHA256 algorithm, the updated section would look similar to this where {SSHA256} has been appended: { "source" : "password", "condition" : { "type" : "text/javascript", "source" : "object.password != null" }, "transform" : { "type" : "text/javascript", "source" : "var hash = \"{SSHA256}\" + source.$;hash;" }, "target" : "userPassword" },
  4. Update the password in IDM/OpenIDM, which will cause the hashed value to be pushed to DS/OpenDJ. You will see something similar to the following in the DS/OpenDJ audit log when this happens: - replace: userPassword userPassword: {SSHA256}zRaha9G3jX+ptpLL79oBDU5wcz48/t+Cd2GOBAlAPbO4PIRR5udD6nGjO6OEgfGh -
  5. Verify DS/OpenDJ is now storing the password hash by viewing the object for the user whose password you updated using ldapsearch, for example​:
    • DS 7 and later: $ ./ldapsearch --port 1389 --bindDN uid=admin --bindPassword password --baseDN "dc=example,dc=com" "(uid=jdoe)" --usePkcs12TrustStore /path/to/ds/config/keystore --trustStorePasswordFile /path/to/ds/config/
    • Pre-DS 7: $ ./ldapsearch --port 1389 --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example,dc=com" "(uid=jdoe)" --trustAll
    Response: dn: uid=jdoe,ou=People,dc=example,dc=com objectClass: person objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: top givenName: Jame description: Created for OpenIDM uid: jdoe cn: Jane Doe sn: Doe telephoneNumber: 1-360-229-7105 userPassword: {SSHA256}zRaha9G3jX+ptpLL79oBDU5wcz48/t+Cd2GOBAlAPbO4PIRR5udD6nGjO6OEgfGh mail:

See Also

How do I change a password storage scheme and apply a new password policy to users in DS/OpenDJ (All versions)?

How do I improve performance when using PBKDF2 storage schemes in DS/OpenDJ (All versions)?

FAQ: Passwords in DS/OpenDJ

Synchronization in IDM/OpenIDM

Synchronization Guide

Security Guide

Related Training


Related Issue Tracker IDs

OPENIDM-11456 (Skip password policy validation if password is hashed)

Copyright and TrademarksCopyright © 2020 ForgeRock, all rights reserved.