Skip to content

Migrate Ldap manager passwords to up-to-date encryption strategy - #7248

Draft
thomaslow wants to merge 3 commits into
kitodo:mainfrom
thomaslow:migrate-ldap-passwords-to-secure-encryption
Draft

Migrate Ldap manager passwords to up-to-date encryption strategy#7248
thomaslow wants to merge 3 commits into
kitodo:mainfrom
thomaslow:migrate-ldap-passwords-to-secure-encryption

Conversation

@thomaslow

@thomaslow thomaslow commented Sep 10, 2026

Copy link
Copy Markdown
Member

This PR addresses two CodeQL security warnings about outdated encryption algorithms:

"Use of a broken or risky cryptographic algorithm" in AESUtil.java:90
"Use of a broken or risky cryptographic algorithm" in AESUtil.java:155

Related Issues

How it works

The class AESUtil is needed to symmetrically encrypt Ldap manager passwords. These passwords are used to write credentials of users to an Ldap server (if configured). The secret key for this encryption can be configured in kitodo_config.properties via security.secret.ldapManagerPassword.

Currently, AESUtil uses the encryption method AES/CBC, which is generally not bad, but a bit outdated. This PR migrates passwords to AES/GCM, which is considered the current standard.

This PR follows a similar strategy as #7188 and the Spring Security "DelegatingPasswordEncoder". It prefixes encrypted passwords with a unique identifier, e.g., {aes-gcm}, which is used to identify the encryption strategy for this password. Passwords that have previously stored without such a prefix are treated as "legacy" and are decrypted with the legacy decryption strategy. In the future, passwords can be easily migrated to new and better algorithms by adding another strategy implementation.

In order to migrate passwords to the newest encryption algorithm, the button LDAP Manager Passwörter migrieren on page "System -> Migrieren" can be used.

Since Kitodo.Production needs to be capable of decrypting legacy passwords for some time, the CodeQL security warning message will remain active. The legacy class AESUtil (now LegacyAesUtil) has been marked as @Deprecated.

UI Changes

The password input for ldap manager passwords was previously set up with redisplay="true", meaning, the actual clear-text password was already embedded in the HTML, but there was no "eye" button for users to display the clear-text password. This PR adds the "eye" button and fixes a simple layout issue (the password input did not stretch to 100% width).

I also added a maxlength restriction of 128 characters to the password input such that you cannot enter passwords that will be encrypted to something that does not fit the managerPassword database column that only supports 255 characters (defined as VARCHAR(255)). A password with 128 characters is encoded with roughly ~250 characters. In case the encoding still doesn't fit, a general "Ldap Server cannot be saved" error is shown to the user (as implemented in the current main branch).

Migration / Release Notes

  • Update encrypted LDAP Manager passwords by clicking on LDAP Manager Passwörter migrieren on page System -> Migrieren

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 42 complexity · 2 duplication

Metric Results
Complexity 42
Duplication 2

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

*/
@Test
public void checkIsEncrypted() throws Exception {
String cipher = LegacyAesUtil.encrypt(INPUT, SECRET);
@Test
public void checkIsEncrypted() throws Exception {
String cipher = LegacyAesUtil.encrypt(INPUT, SECRET);
assertTrue(LegacyAesUtil.isEncrypted(cipher));
assertTrue(LegacyAesUtil.isEncrypted(cipher));

String potentialCipher = "Lorem Ipsum";
assertFalse(LegacyAesUtil.isEncrypted(potentialCipher));

String potentialCipher = "Lorem Ipsum";
assertFalse(LegacyAesUtil.isEncrypted(potentialCipher));
assertFalse(LegacyAesUtil.isEncrypted(Base64.encode(potentialCipher)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants