This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch rc/1.3.5
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit b1979831936b2ed650843eac56d54e28fb2f101b
Author: Hongzhi Gao <761417...@qq.com>
AuthorDate: Wed Jun 18 18:12:20 2025 +0800

    [To dev/1.3] User password encryption upgraded from MD5 to SHA256 (#15762)
    
    * Implement high availability for the C++ client and support tsblock
    
    * fix issues on windows
    
    * User password encryption upgraded from MD5 to SHA256. Existing users' 
passwords will be upgraded upon next login.
    
    * spotless apply
---
 .../iotdb/db/auth/ClusterAuthorityFetcher.java     |  5 +++++
 .../security/encrypt/MessageDigestEncryptTest.java | 12 +++++++++--
 .../commons/auth/authorizer/BasicAuthorizer.java   | 17 +++++++++++++---
 .../security/encrypt/AsymmetricEncrypt.java        | 23 ++++++++++++++++++++--
 .../security/encrypt/MessageDigestEncrypt.java     | 10 +++++-----
 .../org/apache/iotdb/commons/utils/AuthUtils.java  | 22 +++++++++++++++++++--
 6 files changed, 75 insertions(+), 14 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 107561bdca3..70333039957 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
@@ -34,6 +34,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.confignode.rpc.thrift.TAuthizedPatternTreeResp;
 import org.apache.iotdb.confignode.rpc.thrift.TAuthorizerReq;
@@ -396,6 +397,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 2b4dd753f73..56e78f03642 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.getUser(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 e8359bcd070..7a8680a8d9a 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
@@ -27,6 +27,7 @@ import org.apache.iotdb.commons.auth.user.IUserManager;
 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;
@@ -118,9 +119,19 @@ public abstract class BasicAuthorizer implements 
IAuthorizer, IService {
   @Override
   public boolean login(String username, String password) throws AuthException {
     User user = userManager.getUser(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
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 38f8c689b4f..20c991d470a 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
@@ -29,6 +29,7 @@ import 
org.apache.iotdb.commons.exception.IllegalPathException;
 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;
@@ -127,7 +128,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);
   }
 
   /**
@@ -231,7 +249,7 @@ public class AuthUtils {
     return AsymmetricEncryptFactory.getEncryptProvider(
             
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProvider(),
             
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProviderParameter())
-        .encrypt(password);
+        .encrypt(password, AsymmetricEncrypt.DigestAlgorithm.SHA_256);
   }
 
   /**

Reply via email to