This is an automated email from the ASF dual-hosted git repository.
mridulpathak pushed a commit to branch release24.09
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/release24.09 by this push:
new 1af7b3e0f0 Fixed: HashCrypt compares non-PBKDF2 password hashes with
variable-time String.equals() (OFBIZ-13615)
1af7b3e0f0 is described below
commit 1af7b3e0f0857515fdcd91007248ba81c499baff
Author: Mridul Pathak <[email protected]>
AuthorDate: Sat Sep 26 17:33:06 2026 +0530
Fixed: HashCrypt compares non-PBKDF2 password hashes with variable-time
String.equals() (OFBIZ-13615)
doCompareTypePrefix(), doComparePosix() and doCompareBare() compared the
computed hash to the stored hash with String.equals(), which returns at the
first differing character. They now use MessageDigest.isEqual() through a small
helper, matching the constant-time comparison already used by
doComparePbkdf2(). The result of every comparison is unchanged.
---
.../main/java/org/apache/ofbiz/base/crypto/HashCrypt.java | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git
a/framework/base/src/main/java/org/apache/ofbiz/base/crypto/HashCrypt.java
b/framework/base/src/main/java/org/apache/ofbiz/base/crypto/HashCrypt.java
index 4be9e7d564..f425b2bf8f 100644
--- a/framework/base/src/main/java/org/apache/ofbiz/base/crypto/HashCrypt.java
+++ b/framework/base/src/main/java/org/apache/ofbiz/base/crypto/HashCrypt.java
@@ -85,11 +85,11 @@ public class HashCrypt {
byte[] digestBytes = messagedigest.digest();
char[] digestChars = Hex.encodeHex(digestBytes);
String checkCrypted = new String(digestChars);
- if (hashed.equals(checkCrypted)) {
+ if (isEqual(hashed, checkCrypted)) {
return true;
}
// This next block should be removed when all {prefix}oldFunnyHex are
fixed.
- if (hashed.equals(oldFunnyHex(digestBytes))) {
+ if (isEqual(hashed, oldFunnyHex(digestBytes))) {
Debug.logWarning("Warning: detected oldFunnyHex password prefixed
with a hashType; this is not valid, please update the value "
+ "in the database with ({%s}%s)", MODULE, hashType,
checkCrypted);
return true;
@@ -103,7 +103,7 @@ public class HashCrypt {
String hashType = crypted.substring(1, typeEnd);
String salt = crypted.substring(typeEnd + 1, saltEnd);
String hashed = crypted.substring(saltEnd + 1);
- return hashed.equals(getCryptedBytes(hashType, salt, bytes));
+ return isEqual(hashed, getCryptedBytes(hashType, salt, bytes));
}
private static boolean doCompareBare(String crypted, String defaultCrypt,
byte[] bytes) {
@@ -111,7 +111,14 @@ public class HashCrypt {
String hashed = crypted;
MessageDigest messagedigest = getMessageDigest(hashType);
messagedigest.update(bytes);
- return hashed.equals(oldFunnyHex(messagedigest.digest()));
+ return isEqual(hashed, oldFunnyHex(messagedigest.digest()));
+ }
+
+ /**
+ * Compares two hash strings in constant time, so the comparison does not
stop at the first differing character.
+ */
+ private static boolean isEqual(String hashed, String computed) {
+ return MessageDigest.isEqual(hashed.getBytes(StandardCharsets.UTF_8),
computed.getBytes(StandardCharsets.UTF_8));
}
/*