This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new e315e44bf94 User password encryption upgraded from MD5 to SHA256.
(#15680)
e315e44bf94 is described below
commit e315e44bf94c01c2c0f6b1a636ee4a6557f75368
Author: Hongzhi Gao <[email protected]>
AuthorDate: Mon Jun 16 12:24:44 2025 +0800
User password encryption upgraded from MD5 to SHA256. (#15680)
* User password encryption upgraded from MD5 to SHA256. Existing users'
passwords will be upgraded upon next login.
* fix some issues
* fix login4pipe
---
.../iotdb/db/auth/ClusterAuthorityFetcher.java | 5 +++
.../security/encrypt/MessageDigestEncryptTest.java | 12 +++++--
.../commons/auth/authorizer/BasicAuthorizer.java | 42 +++++++++++++++++-----
.../security/encrypt/AsymmetricEncrypt.java | 23 ++++++++++--
.../security/encrypt/MessageDigestEncrypt.java | 10 +++---
.../org/apache/iotdb/commons/utils/AuthUtils.java | 22 ++++++++++--
6 files changed, 94 insertions(+), 20 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java
index 23b0efcd1e2..764038c1641 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java
@@ -36,6 +36,7 @@ import org.apache.iotdb.commons.exception.IoTDBException;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathPatternTree;
+import org.apache.iotdb.commons.security.encrypt.AsymmetricEncrypt;
import org.apache.iotdb.commons.utils.AuthUtils;
import org.apache.iotdb.commons.utils.TestOnly;
import org.apache.iotdb.confignode.rpc.thrift.TAuthizedPatternTreeResp;
@@ -481,6 +482,10 @@ public class ClusterAuthorityFetcher implements
IAuthorityFetcher {
return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
} else if (password != null && AuthUtils.validatePassword(password,
user.getPassword())) {
return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
+ } else if (password != null
+ && AuthUtils.validatePassword(
+ password, user.getPassword(),
AsymmetricEncrypt.DigestAlgorithm.MD5)) {
+ return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
} else {
return RpcUtils.getStatus(TSStatusCode.WRONG_LOGIN_PASSWORD,
"Authentication failed.");
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/security/encrypt/MessageDigestEncryptTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/security/encrypt/MessageDigestEncryptTest.java
index e93894dbf7f..1468d44022e 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/security/encrypt/MessageDigestEncryptTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/security/encrypt/MessageDigestEncryptTest.java
@@ -25,6 +25,7 @@ import
org.apache.iotdb.commons.auth.user.LocalFileUserManager;
import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.exception.IllegalPathException;
import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.security.encrypt.AsymmetricEncrypt;
import org.apache.iotdb.commons.security.encrypt.MessageDigestEncrypt;
import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.apache.iotdb.db.utils.constant.TestConstant;
@@ -85,13 +86,20 @@ public class MessageDigestEncryptTest {
for (User user1 : users) {
user = manager.getEntity(user1.getName());
assertEquals(user1.getName(), user.getName());
- assertEquals(messageDigestEncrypt.encrypt(user1.getPassword()),
user.getPassword());
+ assertEquals(
+ messageDigestEncrypt.encrypt(
+ user1.getPassword(), AsymmetricEncrypt.DigestAlgorithm.SHA_256),
+ user.getPassword());
}
}
@Test
public void testMessageDigestValidatePassword() {
String password = "root";
- assertTrue(messageDigestEncrypt.validate(password,
messageDigestEncrypt.encrypt(password)));
+ assertTrue(
+ messageDigestEncrypt.validate(
+ password,
+ messageDigestEncrypt.encrypt(password,
AsymmetricEncrypt.DigestAlgorithm.SHA_256),
+ AsymmetricEncrypt.DigestAlgorithm.SHA_256));
}
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
index 89b7c2d1a10..543c034b100 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
@@ -28,6 +28,7 @@ import org.apache.iotdb.commons.auth.user.BasicUserManager;
import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.exception.StartupException;
import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.security.encrypt.AsymmetricEncrypt;
import org.apache.iotdb.commons.service.IService;
import org.apache.iotdb.commons.service.ServiceType;
import org.apache.iotdb.commons.utils.AuthUtils;
@@ -109,20 +110,43 @@ public abstract class BasicAuthorizer implements
IAuthorizer, IService {
@Override
public boolean login(String username, String password) throws AuthException {
User user = userManager.getEntity(username);
- return user != null
- && password != null
- && AuthUtils.validatePassword(password, user.getPassword());
+ if (user == null || password == null) {
+ return false;
+ }
+ if (AuthUtils.validatePassword(
+ password, user.getPassword(),
AsymmetricEncrypt.DigestAlgorithm.SHA_256)) {
+ return true;
+ }
+ if (AuthUtils.validatePassword(
+ password, user.getPassword(), AsymmetricEncrypt.DigestAlgorithm.MD5)) {
+ userManager.updateUserPassword(username, password);
+ return true;
+ }
+ return false;
}
@Override
public String login4Pipe(final String username, final String password) {
final User user = userManager.getEntity(username);
- return (user != null
- && password != null
- && AuthUtils.validatePassword(password, user.getPassword())
- || Objects.isNull(password))
- ? user.getPassword()
- : null;
+ if (Objects.isNull(password)) {
+ return user.getPassword();
+ }
+ if (user == null) {
+ return null;
+ }
+ if (AuthUtils.validatePassword(
+ password, user.getPassword(),
AsymmetricEncrypt.DigestAlgorithm.SHA_256)) {
+ return user.getPassword();
+ }
+ if (AuthUtils.validatePassword(
+ password, user.getPassword(), AsymmetricEncrypt.DigestAlgorithm.MD5)) {
+ try {
+ userManager.updateUserPassword(username, password);
+ } catch (AuthException ignore) {
+ }
+ return userManager.getEntity(username).getPassword();
+ }
+ return null;
}
@Override
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/AsymmetricEncrypt.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/AsymmetricEncrypt.java
index 58ba0868763..7ede0bb6cf8 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/AsymmetricEncrypt.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/AsymmetricEncrypt.java
@@ -21,6 +21,25 @@ package org.apache.iotdb.commons.security.encrypt;
public interface AsymmetricEncrypt {
+ /**
+ * Defines cryptographic hash algorithms supported by the system. Each enum
constant represents a
+ * specific message digest algorithm compatible with {@link
java.security.MessageDigest}.
+ */
+ enum DigestAlgorithm {
+ MD5("MD5"),
+ SHA_256("SHA-256");
+
+ private final String algorithmName;
+
+ DigestAlgorithm(String algorithmName) {
+ this.algorithmName = algorithmName;
+ }
+
+ public String getAlgorithmName() {
+ return this.algorithmName;
+ }
+ }
+
/**
* init some providerParameter
*
@@ -34,7 +53,7 @@ public interface AsymmetricEncrypt {
* @param originPassword password to be crypt
* @return encrypt password
*/
- String encrypt(String originPassword);
+ String encrypt(String originPassword, DigestAlgorithm digestAlgorithm);
/**
* validate originPassword and encryptPassword
@@ -43,5 +62,5 @@ public interface AsymmetricEncrypt {
* @param encryptPassword encrypt password
* @return true if validate success
*/
- boolean validate(String originPassword, String encryptPassword);
+ boolean validate(String originPassword, String encryptPassword,
DigestAlgorithm digestAlgorithm);
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/MessageDigestEncrypt.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/MessageDigestEncrypt.java
index 63ca50413ac..91d84db33c6 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/MessageDigestEncrypt.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/MessageDigestEncrypt.java
@@ -29,16 +29,15 @@ import java.security.NoSuchAlgorithmException;
public class MessageDigestEncrypt implements AsymmetricEncrypt {
private static final Logger logger =
LoggerFactory.getLogger(MessageDigestEncrypt.class);
- private static final String ENCRYPT_ALGORITHM = "MD5";
private static final String STRING_ENCODING = "utf-8";
@Override
public void init(String providerParameters) {}
@Override
- public String encrypt(String originPassword) {
+ public String encrypt(String originPassword, DigestAlgorithm
digestAlgorithm) {
try {
- MessageDigest messageDigest =
MessageDigest.getInstance(ENCRYPT_ALGORITHM);
+ MessageDigest messageDigest =
MessageDigest.getInstance(digestAlgorithm.getAlgorithmName());
messageDigest.update(originPassword.getBytes(STRING_ENCODING));
return new String(messageDigest.digest(), STRING_ENCODING);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
@@ -48,10 +47,11 @@ public class MessageDigestEncrypt implements
AsymmetricEncrypt {
}
@Override
- public boolean validate(String originPassword, String encryptPassword) {
+ public boolean validate(
+ String originPassword, String encryptPassword, DigestAlgorithm
digestAlgorithm) {
if (originPassword == null) {
return false;
}
- return encrypt(originPassword).equals(encryptPassword);
+ return encrypt(originPassword, digestAlgorithm).equals(encryptPassword);
}
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java
index 64e1420e081..d5144efa485 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathDeserializeUtil;
import org.apache.iotdb.commons.path.PathPatternUtil;
+import org.apache.iotdb.commons.security.encrypt.AsymmetricEncrypt;
import org.apache.iotdb.commons.security.encrypt.AsymmetricEncryptFactory;
import org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp;
import org.apache.iotdb.confignode.rpc.thrift.TRoleResp;
@@ -81,7 +82,24 @@ public class AuthUtils {
return AsymmetricEncryptFactory.getEncryptProvider(
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProvider(),
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProviderParameter())
- .validate(originPassword, encryptPassword);
+ .validate(originPassword, encryptPassword,
AsymmetricEncrypt.DigestAlgorithm.SHA_256);
+ }
+
+ /**
+ * Checking whether origin password is mapping to encrypt password by
encryption
+ *
+ * @param originPassword the password before encryption
+ * @param encryptPassword the password after encryption
+ * @param digestAlgorithm the algorithm for encryption
+ */
+ public static boolean validatePassword(
+ String originPassword,
+ String encryptPassword,
+ AsymmetricEncrypt.DigestAlgorithm digestAlgorithm) {
+ return AsymmetricEncryptFactory.getEncryptProvider(
+
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProvider(),
+
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProviderParameter())
+ .validate(originPassword, encryptPassword, digestAlgorithm);
}
/**
@@ -171,7 +189,7 @@ public class AuthUtils {
return AsymmetricEncryptFactory.getEncryptProvider(
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProvider(),
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProviderParameter())
- .encrypt(password);
+ .encrypt(password, AsymmetricEncrypt.DigestAlgorithm.SHA_256);
}
/**