Permalink
Show file tree
Hide file tree
2 changes: 2 additions & 0 deletions
2
modules/common-jpa-impl/src/main/java/org/opencastproject/security/impl/jpa/JpaUser.java
61 changes: 58 additions & 3 deletions
61
...userdirectory/src/main/java/org/opencastproject/userdirectory/JpaUserAndRoleProvider.java
20 changes: 20 additions & 0 deletions
20
.../userdirectory/src/main/java/org/opencastproject/userdirectory/endpoint/UserEndpoint.java
9 changes: 5 additions & 4 deletions
9
...es/userdirectory/src/test/java/org/opencastproject/userdirectory/JpaUserProviderTest.java
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Replace MD5 with bcrypt for password hashing
User passwords are stored in the database using the rather outdated and cryptographically insecure MD5 hash algorithm. Furthermore, the hashes are salted using the username instead of a random salt, causing hashes for users with the same username and password to collide which is problematic especially for popular users like the default admin user. This essentially means that for an attacker, it might be feasible to reconstruct a user's password given access to these hashes. Note that attackers needing access to the hashes means that they must gain access to the database in which these are stored first to be able to start cracking the passwords. Patches The patch makes Opencast now uses the modern and much stronger bcrypt password hashing algorithm for storing passwords. Note, that old hashes remain MD5 until the password is updated. For a list of users whose password hashes are stored using MD5, the REST endpoint `/user-utils/users/md5.json` is added.
- Loading branch information
Showing
7 changed files
with
188 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 0 additions & 54 deletions
54
modules/common/src/main/java/org/opencastproject/util/PasswordEncoder.java
This file was deleted.
Oops, something went wrong.
96 changes: 96 additions & 0 deletions
96
modules/kernel/src/main/java/org/opencastproject/kernel/security/CustomPasswordEncoder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| /** | ||
| * Licensed to The Apereo Foundation under one or more contributor license | ||
| * agreements. See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * | ||
| * The Apereo Foundation licenses this file to you under the Educational | ||
| * Community License, Version 2.0 (the "License"); you may not use this file | ||
| * except in compliance with the License. You may obtain a copy of the License | ||
| * at: | ||
| * | ||
| * http://opensource.org/licenses/ecl2.txt | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| * License for the specific language governing permissions and limitations under | ||
| * the License. | ||
| * | ||
| */ | ||
|
|
||
| package org.opencastproject.kernel.security; | ||
|
|
||
| import org.apache.commons.codec.digest.DigestUtils; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
| import org.springframework.security.authentication.encoding.PasswordEncoder; | ||
| import org.springframework.security.crypto.bcrypt.BCrypt; | ||
|
|
||
| /** | ||
| * | ||
| */ | ||
| public class CustomPasswordEncoder implements PasswordEncoder { | ||
| private Logger logger = LoggerFactory.getLogger(CustomPasswordEncoder.class); | ||
|
|
||
| /** | ||
| * Encode the raw password for storage using BCrypt. | ||
| * @param rawPassword raw password to encrypt/hash | ||
| * @return hashed password | ||
| */ | ||
| public String encodePassword(final String rawPassword) { | ||
| return encodePassword(rawPassword, null); | ||
| } | ||
|
|
||
| /** | ||
| * Encode the raw password for storage using BCrypt. | ||
| * @param rawPassword raw password to encrypt/hash | ||
| * @param ignored This parameter will not be used. A random salt is generated by BCrypt. | ||
| * @return hashed password | ||
| */ | ||
| @Override | ||
| public String encodePassword(final String rawPassword, final Object ignored) { | ||
| return BCrypt.hashpw(rawPassword, BCrypt.gensalt()); | ||
| } | ||
|
|
||
| /** | ||
| * Verify the encoded password obtained from storage matches the submitted raw | ||
| * password after it too is encoded. Returns true if the passwords match, false if | ||
| * they do not. The stored password itself is never decoded. | ||
| * | ||
| * @param rawPassword the raw password to encode and match | ||
| * @param encodedPassword the encoded password from storage to compare with | ||
| * @return true if the raw password, after encoding, matches the encoded password from storage | ||
| */ | ||
| @Override | ||
| public boolean isPasswordValid(String encodedPassword, String rawPassword, Object salt) { | ||
| // Test MD5 encoded hash | ||
| if (encodedPassword.length() == 32) { | ||
| final String hash = md5Encode(rawPassword, salt); | ||
| logger.debug("Checking md5 hashed password '{}' against encoded password '{}'", hash, encodedPassword); | ||
| return hash.equals(encodedPassword); | ||
| } | ||
|
|
||
| // Test BCrypt encoded hash | ||
| logger.debug("Verifying BCrypt hash {}", encodedPassword); | ||
| return BCrypt.checkpw(rawPassword, encodedPassword); | ||
| } | ||
|
|
||
| /** | ||
| * Encode a clear text password using Opencast's legacy MD5 based hashing with salt. | ||
| * The username was used as salt for this. | ||
| * | ||
| * @param clearText | ||
| * the password | ||
| * @param salt | ||
| * the salt | ||
| * @return the hashed password | ||
| * @throws IllegalArgumentException | ||
| * if clearText or salt are null | ||
| */ | ||
| public static String md5Encode(String clearText, Object salt) throws IllegalArgumentException { | ||
| if (clearText == null || salt == null) | ||
| throw new IllegalArgumentException("clearText and salt must not be null"); | ||
| return DigestUtils.md5Hex(clearText + "{" + salt.toString() + "}"); | ||
| } | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters