Password Storage Configuration

Last modified 09 Feb 2024 14:39 +01:00
Since 3.6
This functionality is available since version 3.6.

Introduction

Passwords are sensitive, therefore they were always be handled with utmost care in midPoint. MidPoint has a special data type to store sensitive information (ProtectedString) and there is special component that takes care of protecting the values before storage.

Storing Encrypted Passwords

MidPoint has stored passwords in encrypted forms from the very beginning. And this is still the default setting. In this case midPoint encrypts the password with a symmetric cipher before storage. Using symmetric encryption allows midPoint to get a cleartext value of the password if needed. And this is really needed relatively often in the identity management world. Almost all the target resources need clear text password to create a working account. This is easy to do when a midPoint user is created as at that point we usually have (generated) cleartext password. But if an account is assigned at a later time then we have a problem. We need cleartext password to create this new account. Therefore midPoint stored the passwords in encrypted form. This seems to be a common practice in the IDM field.

That encryption was the only practical measure to provide at least some protection for the password. We take care to select a good cipher (AES), generate random key for every midPoint deployment, store the key in the keystore and not in the database and so on. However as midPoint needs to be able to get a cleartext version of the password at any time it is not really possible to provide complete protection for the password.

The passwords are encrypted using the following parameters:

JCE extension installed JCE extension not installed

Cipher

AES

AES

Key size (bits)

256

128

Password Hashing

MidPoint 3.6 introduces ability to hash passwords instead of encrypting them for storage. This approach to password storage is more secure, but it has its drawbacks.MidPoint knows cleartext password only when midPoint user is created or when user changes the password. It does not know the password at other times. Therefore if a new account is assigned to the user, the valid password cannot be set for that account. We can either create a password-less account (if the resource allows it) or generate a randomly-generated password. Either way that account will not be be usable until is it explicitly initialized by the user.

The process works like this: user will get mail notification that there are new accounts ready for him and that he needs to initialize them. The notification will contain link to the midPoint end-user interface. The user will follow the link and gets to the account initialization page. He needs to enter his current midPoint password first. This is both a form of user authentication but also a way how midPoint gets cleartext version of user’s password. MidPoint then displays list of new user accounts and offers user the option to initialize them. The initialization means setting the password to those accounts to make them usable.

The password is hashed using the following parameters:

Algorithm PBKDF2 with HMAC SHA512

Key size (bits)
("hash size")

256

Work factor (iterations)

10 000

Salt size (bits)

32

Configuring the Storage Mechanism

It is clear that in this case one size does not fit all. Some midPoint deployment will prefer ease of use and operational advantages of password encryption. Other deployment will choose hashing for security reasons and accept the inconvenience of account initialization mechanism. Therefore the password storage mechanism is configurable. The storage mechanism can be configured in security policy:

<securityPolicy>
    ...
    <credentials>
        <password>
            <storageMethod>
                <storageType>hashing</storageType>
            </storageMethod>
        </password>
    </credentials>
</securityPolicy>

Possible storage type values are:

Type Meaning

encryption

Credential will be stored in an encrypted form. This is a symmetric (reversible) encryption. MidPoint will be able to get a cleartext form of the credential if needed.

hashing

Credential will be stored in a hashed form. One-way (irreversible) cryptographic hash or key derivation function will be used to transform the credential before storage. MidPoint will NOT be able to get a cleartext form of the credential, but it can still compare credential values.

none

MidPoint will not store the credential at all. MidPoint will only work with credential in the memory while it is needed to complete current operation. The credential will be discarded after the operation.

This is only partially implemented in midPoint 3.6 and it is not fully supported. MidPoint should be able not to store the credentials when this setting is used. But there may be side effects that are not completely addressed yet. This is not entirely tests and not supported. Use at your own risk.

Account Lifecycle and Initialization

Accounts that were created and were not yet initialized are marked in midPoint by using the lifecycle state property. The uninitialized accounts are in the proposed lifecycle state. Account initialization will transition the account to the active lifecycle state.

Simple account activation notifier
<accountActivationNotifier>
	<recipientExpression>
		<script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:type="c:ScriptExpressionEvaluatorType">
			<code>
            	return requestee.getEmailAddress()
			</code>
		</script>
	</recipientExpression>
	<transport>mail</transport>
    <confirmationMethod>link</confirmationMethod>
</accountActivationNotifier>
Custom account activation notifier
<accountActivationNotifier>
	<recipientExpression>
    	<script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:type="c:ScriptExpressionEvaluatorType">
        	<code>
				return requestee.getEmailAddress()
			</code>
		</script>
	</recipientExpression>
	<bodyExpression>
		<script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:type="c:ScriptExpressionEvaluatorType">
			<code>
            	import com.evolveum.midpoint.notifications.api.events.ModelEvent
				modelEvent = (ModelEvent) event
				newUser = modelEvent.getFocusContext().getObjectNew();
				userType = newUser.asObjectable();

                message = "Dear " + userType.getGivenName() + ",\n\n" +
                            "your account was successfully created. To activate your account click on the activation link below in the                  email."
				accountsToActivate = "Shadow to be activated: \n";
				shadows = getMidpointFunctions().getShadowsToActivate(modelEvent.getProjectionContexts())
				for (shadow in shadows) {
					accountsToActivate = accountsToActivate + shadow.asPrismObject().debugDump() + "\n";
				}
				link = midpoint.createAccountActivationLink(userType);
				bodyMessage = message + "\n\n" + link + "\n\n" + accountsToActivate;
                return bodyMessage;
			</code>
		</script>
	</bodyExpression>
	<transport>mail</transport>
	<confirmationMethod>link</confirmationMethod>
</accountActivationNotifier>

Password History

The default setting for password history storage is hashing. This can also be configured in security policy:

<securityPolicy>
    ...
    <credentials>
        <password>
            ...
            <historyStorageMethod>
                <storageType>encryption</storageType>
            </historyStorageMethod>
        </password>
    </credentials>
</securityPolicy>

Password history in midPoint 3.5.1 and earlier had a different default. Hasing was not supported at that time therefore that password history entries were stored in encrypted form. The old password history entries will remain in the form in which they were originally stored after upgrade to midPoint 3.6 and/or after change of the storage scheme.

Misc

  • If password storage scheme is changed then the existing passwords stored in the system will not be changed. If they were encrypted they will remain encrypted. They will not be re-hashed. Currently there is no task that could support this migration process. The only method how to change the stored version of the passwords is the usual password change process. However, please be careful about password history. Please check that the old passwords are stored in the password history in appropriate form.

  • When switching to password hashing do not forget to change the password of the administrator user - or any other existing users that were used for configuration. Otherwise the password will remain in encrypted form and it will not be hashed.

Was this page helpful?
YES NO
Thanks for your feedback