PingDS 7.5.1

Change password storage

What seemed a secure password storage scheme a few years ago no longer looks safe. You can configure DS to migrate to stronger password storage.

Description

Estimated time to complete: 30 minutes

With a reversible encryption scheme, an attacker who gains access to the server files can recover all the plaintext passwords. With a strong one-way hash scheme, the attacker must use brute force methods for each password.

However, not all one-way hash schemes are safe, either. Older password storage schemes, such as the salted Secure Hash Algorithm (SHA-1) schemes, use one-way hash functions designed for message authentication and digital signatures. SHA-1 schemes are fast; a server processes authentications with low latency and high throughput. On the downside, high-performance algorithms also make brute force attack techniques more effective. Modern off-the-shelf GPUs can calculate billions of SHA-1 hashes per second. Dedicated hardware can calculate even more hashes per second.

Goals

In completing this use case, you learn to:

  • Discover password policies using outdated password storage schemes.

  • List accounts using outdated password storage schemes.

  • Create a replicated password policy and configure its password storage scheme settings.

  • Assign accounts a password policy.

Example scenario

The security team where Pat works has mandated passwords must be stored with a computationally intensive one-way hash, such as Argon2, Bcrypt, PBKDF2, or PKCS5S2.

Pat knows the default password storage scheme for the DS directory service has not changed in years. Many user accounts still have salted SHA-1-based password storage.

Pat considers the options and decides to move to a PBKDF2-based scheme. Pat plans to show how to switch to PBKDF2 and to get the other identity administrators to review the process.

At this point, the security team has not communicated a due date to implement the mandate. Pat expects the change to be transparent for users and application developers.

As a directory service administrator, Pat must work with the deployment team to make sure DS systems have enough CPU. PBKDF2 uses far more CPU resources than outdated storage schemes.

Prerequisites

Knowledge

Before you start, make sure you have the same background knowledge as Pat:

Background

The problem

Sometimes, people ask why DS doesn’t provide a tool to move passwords from one storage scheme to another.

Pat explains DS uses one-way hash functions to store passwords. These are one-way functions because going from a password to a hash is deterministic and straightforward. Going from a hash to a password is hard. For computationally intensive schemes like PBKDF2, going from a hash to a password is effectively impossible.

Even given the PBKDF2-based password hashes for all the accounts in the directory service, you’d spend plenty of money and computer resources cracking any of them to recover an original password.

Any tool to move passwords from one storage scheme to another must first crack every password hash. For this reason, DS does not provide such a tool, and there are no plans to develop one.

The solution

One possible solution is to change the storage scheme in password policies, disable the target storage schemes, and require users to reset the passwords for their accounts; however, this can be disruptive.

Pat knows a less disruptive solution is to wait until the next successful authentication, then let DS store the password with the new storage scheme.

When you authenticate with a DN and password—​an LDAP simple bind—​you supply the password. If the authentication succeeds, the password is valid. DS still has the password at this time, so it can hash the password according to the new scheme and remove the hash computed by the old scheme.

In DS, the password policy defines the storage scheme to use. As an administrator, Pat configures a password policy to deprecate the old scheme in favor of the new scheme. Pat then waits for accounts to bind and lets DS update the storage scheme.

Constraints

Waiting for accounts to bind is not a problem unless there are time constraints.

For example, if there’s a mandate to move away from the deprecated scheme by a target date, then Pat will have to effectively lock "inactive" accounts. Those accounts must reset their passwords after the date.

As an administrator, Pat can implement this by disabling the deprecated password storage scheme on the target date. Accounts cannot bind with a password stored using a disabled scheme.

Pat knows to warn application owners and developers of end-user UIs and self-service account management tools "inactive" accounts cannot authenticate when their passwords still use the old scheme after the target date.

Applications can rely on account usability features to discover why LDAP binds fail. Developers of end-user tools can use the hints in their applications to reset user passwords and prompt users to set new passwords.

Tasks

Pat demonstrates how to change password storage with a single DS server using the evaluation profile. The order of the tasks is the same in deployment, but the target storage schemes can differ.

Pat shows the process with a subentry password policy. You create an LDAP subentry and DS replicates it to the other replicas. If you use per-server password policies instead, you must edit the configuration for each DS replica.

Task 1: Set up DS

  1. Create a deployment ID to use when setting up DS:

    $ /path/to/opendj/bin/dskeymgr create-deployment-id --deploymentIdPassword password
    <deployment-id>
    $ export DEPLOYMENT_ID=<deployment-id>
  2. Set up a single DS server using the evaluation profile with an outdated password storage scheme:

    $ /path/to/opendj/setup \
     --serverId evaluation-only \
     --deploymentId $DEPLOYMENT_ID \
     --deploymentIdPassword password \
     --rootUserDn uid=admin \
     --rootUserPassword password \
     --monitorUserPassword password \
     --hostname localhost \
     --ldapPort 1389 \
     --ldapsPort 1636 \
     --httpsPort 8443 \
     --adminConnectorPort 4444 \
     --replicationPort 8989 \
     --profile ds-evaluation \
     --set ds-evaluation/useOutdatedPasswordStorage:true \
     --start \
     --acceptLicense

    The useOutdatedPasswordStorage sets the password storage scheme for users to Salted SHA-512.

Task 2: List password policies using outdated schemes

To show the process, Pat deprecates the outdated storage scheme in favor of a new stronger storage scheme.

  1. List all available password storage schemes:

    $ /path/to/opendj/bin/dsconfig \
     list-password-storage-schemes \
     --hostname localhost \
     --port 4444 \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password \
     --no-prompt
    Password Storage Scheme : Type               : enabled
    ------------------------:--------------------:--------
    3DES (DEPRECATED)       : triple-des         : false
    AES (LEGACY)            : aes                : false
    Argon2                  : argon2             : true
    Base64 (LEGACY)         : base64             : false
    Bcrypt                  : bcrypt             : true
    Blowfish (DEPRECATED)   : blowfish           : false
    Clear (LEGACY)          : clear              : false
    CRYPT                   : crypt              : false
    PBKDF2                  : pbkdf2             : false
    PBKDF2-HMAC-SHA256      : pbkdf2-hmac-sha256 : true
    PBKDF2-HMAC-SHA512      : pbkdf2-hmac-sha512 : true
    PKCS5S2                 : pkcs5s2            : false
    Salted SHA-1 (LEGACY)   : salted-sha1        : false
    Salted SHA-256          : salted-sha256      : false
    Salted SHA-384          : salted-sha384      : false
    Salted SHA-512          : salted-sha512      : true
    SCRAM-SHA-256           : scram-sha256       : true
    SCRAM-SHA-512           : scram-sha512       : true
    SHA-1 (LEGACY)          : sha1               : false

    Accounts cannot authenticate with a password if their password policy depends on a disabled password storage scheme. Only the enabled password storage schemes (enabled: true) matter for this procedure:

    • Argon2

    • Bcrypt

    • PBKDF2-HMAC-SHA256

    • PBKDF2-HMAC-SHA512

    • Salted SHA-512

    • SCRAM-SHA-256

    • SCRAM-SHA-512

    For this example, Pat migrates passwords away from Salted SHA-512. The others are stronger password storage schemes.

  2. List the per-server password policies to identify any that use the outdated scheme.

    $ /path/to/opendj/bin/dsconfig \
     list-password-policies \
     --hostname localhost \
     --port 4444 \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password \
     --no-prompt
    Password Policy         : Type            : password-attribute : default-password-storage-scheme
    ------------------------:-----------------:--------------------:--------------------------------
    Default Password Policy : password-policy : userPassword       : Salted SHA-512
    Root Password Policy    : password-policy : userPassword       : PBKDF2-HMAC-SHA256

    The Default Password Policy uses the outdated storage scheme:

    • The Default Password Policy applies to accounts in user and application data.

    • The Root Password Policy applies to DS service accounts, such as the directory superuser (uid=admin).

  3. List subentry password policies to check for any using the outdated scheme.

    $ /path/to/opendj/bin/ldapsearch \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password \
     --baseDn "" \
     "(&(objectClass=subEntry)(objectClass=ds-pwp-password-policy))"

    The command returns nothing; DS has no subentry password policies configured for the evaluation profile.

Task 3: List accounts using outdated schemes

DS has a userPassword index to the directory entries using each password scheme.

  1. List the accounts using the outdated scheme.

    This command uses a filter with an extensible match comparison, 1.3.6.1.4.1.36733.2.1.4.14:=Salted SHA-512. The object identifier corresponds to password storage scheme quality match syntax. The filter matches entries whose password is stored with Salted SHA-512 (SSHA512):

    $ /path/to/opendj/bin/ldapsearch \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password \
     --baseDn dc=example,dc=com \
      "(userPassword:1.3.6.1.4.1.36733.2.1.4.14:=SSHA512)" 1.1

    An attribute list of 1.1 means the search should not return attribute values, just DNs.

    If you have multiple password policies with outdated storage schemes, search like this for each one.

    The response can be empty, meaning no accounts use the storage scheme. If a password policy uses an outdated password storage scheme, but no accounts use it, update the password policy to deprecate the outdated scheme. Double-check the response is still empty, and disable the outdated scheme in each DS configuration to prevent its use.

  2. If you want to check which password policy an account has, request pwdPolicySubentry:

    $ /path/to/opendj/bin/ldapsearch \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password \
     --baseDn dc=example,dc=com \
     "(cn=Babs Jensen)" \
     pwdPolicySubentry
    dn: uid=bjensen,ou=People,dc=example,dc=com
    pwdPolicySubentry: cn=Default Password Policy,cn=Password Policies,cn=config

    The pwdPolicySubentry has the DN of the applicable password policy for the entry. You could use pwdPolicySubentry instead of 1.1 in the previous step to show the attribute for each user.

Task 4: Move accounts to the new scheme

These steps deprecate Salted SHA-512 in favor of PBKDF2-HMAC-256:

  1. Configure a password policy to deprecate the outdated scheme.

    $ /path/to/opendj/bin/ldapmodify \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password  << EOF
    dn: cn=New password policy,dc=example,dc=com
    objectClass: top
    objectClass: subentry
    objectClass: ds-pwp-password-policy
    objectClass: ds-pwp-validator
    objectClass: ds-pwp-length-based-validator
    cn: New password policy
    ds-pwp-password-attribute: userPassword
    ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
    ds-pwp-deprecated-password-storage-scheme: Salted SHA-512
    ds-pwp-length-based-min-password-length: 8
    subtreeSpecification: {base "", specificationFilter "(userPassword=*)" }
    EOF
    # ADD operation successful for DN cn=New password policy,dc=example,dc=com

    The subtreeSpecification applies the password policy to all accounts under dc=example,dc=com with a userPassword attribute.

  2. Check the new policies apply as expected.

    The following command shows the new policy applies to a user account:

    $ /path/to/opendj/bin/ldapsearch \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password \
     --baseDn dc=example,dc=com \
     "(cn=Babs Jensen)" \
     pwdPolicySubentry userPassword
    dn: uid=bjensen,ou=People,dc=example,dc=com
    userPassword: {SSHA512}<hash>
    pwdPolicySubentry: cn=New password policy,dc=example,dc=com

    The password is still hashed with the old scheme. The user hasn’t authenticated since the password policy change.

  3. Wait for accounts to bind with password-based authentication.

    You can check progress using the searches described in Task 3: List accounts using outdated schemes.

  4. (Optional) When enough accounts have changed storage schemes, disable stale password policies and the outdated scheme.

Task 5: Plan any necessary communications

When you have no time constraints, there’s nothing to communicate to application developers or end users. Make sure DS systems have the resources to process the stronger password policy; communicate about this with those providing systems for testing and deployment. Eventually, DS updates the password storage scheme for all active accounts.

If you have a due date to finish the move, you must disable the outdated scheme at that time:

$ /path/to/opendj/bin/dsconfig \
 set-password-storage-scheme-prop \
 --scheme-name "Salted SHA-512" \
 --set enabled:false \
 --hostname localhost \
 --port 4444 \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password \
 --no-prompt

This has the effect of locking inactive accounts—​those who didn’t authenticate before the date—​because they are stuck with the disabled storage scheme. An administrator must reset the passwords to activate the accounts.

  • Plan with other identity administrators and identity application developers how to automate the password reset and change process to active locked accounts.

    In a Ping Identity Platform deployment, you can configure self-service features to help end users help themselves.

  • If possible, let end users know they need to sign on before the due date to keep their accounts active.

    Let them know inactive accounts are locked out after the due date, and describe how they can activate their accounts after the lockout.

Validation

Display a user’s password before and after authentication to confirm the policy causes DS to update how it stores the password.

  1. Read a userPassword as directory superuser to display the password storage scheme:

    $ /path/to/opendj/bin/ldapsearch \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password \
     --baseDn dc=example,dc=com \
     "(cn=Babs Jensen)" \
     userPassword
    dn: uid=bjensen,ou=People,dc=example,dc=com
    userPassword: {SSHA512}<hash>

    The attribute shows the password storage scheme in braces before the hash. The user has not authenticated since the policy change. The scheme is still Salted SHA-512 (SSHA512).

  2. Read the userPassword again as the user to display the password storage scheme:

    $ /path/to/opendj/bin/ldapsearch \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=bjensen,ou=People,dc=example,dc=com \
     --bindPassword hifalutin \
     --baseDn dc=example,dc=com \
     "(cn=Babs Jensen)" \
     userPassword
    dn: uid=bjensen,ou=People,dc=example,dc=com
    userPassword: {PBKDF2-HMAC-SHA256}10:<hash>

    The --bindDn and --bindPassword indicate the user authenticates with an LDAP simple bind. DS updates the hash when the user authenticates. The scheme is now PBKDF2-HMAC-SHA256.

What’s next

After demonstrating the process, Pat implements plans to deprecate outdated password storage schemes in deployment.

Pat is careful to make sure DS systems have the resources to process PBKDF2 hashes, in particular for binds. For example, Pat can use the authrate command to generate LDAP binds before and after the change. Pat can also review logs and monitoring data from the deployment to estimate peak bind rates.

When you install DS, the setup command configures a PBKDF2-HMAC-SHA256 password storage scheme with 10 iterations instead of the default 10,000 iterations.

The server’s default password policy uses this storage scheme.

When DS systems have sufficient resources, Pat can increase the number of iterations for the PBKDF2-HMAC-SHA256 scheme; for example, setting pbkdf2-iterations: 10000 and rehash-policy: only-increase in the PBKDF2-HMAC-SHA256 scheme configuration. DS updates the password storage hash for an account on the next successful authentication.

Explore further

This use case can serve as a template for DS test and production deployments. Adapt this example for deployment:

  • Review the password storage schemes used in deployment to determine what to change.

  • Make sure the directory service has appropriate resources to sustain authentication rates after moving to a resource-intensive password storage scheme.

  • Plan communications as necessary.

Reference material

Reference

Description

DS password policy and storage schemes

Supported password storage schemes

About LDAP bind operations

Performance tool for generating LDAP bind operations

Client-side password and account management