Skip to content

Commit e315e44

Browse files
authored
User password encryption upgraded from MD5 to SHA256. (apache#15680)
* User password encryption upgraded from MD5 to SHA256. Existing users' passwords will be upgraded upon next login. * fix some issues * fix login4pipe
1 parent 3e6aaa3 commit e315e44

File tree

6 files changed

+94
-20
lines changed

6 files changed

+94
-20
lines changed

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.apache.iotdb.commons.exception.MetadataException;
3737
import org.apache.iotdb.commons.path.PartialPath;
3838
import org.apache.iotdb.commons.path.PathPatternTree;
39+
import org.apache.iotdb.commons.security.encrypt.AsymmetricEncrypt;
3940
import org.apache.iotdb.commons.utils.AuthUtils;
4041
import org.apache.iotdb.commons.utils.TestOnly;
4142
import org.apache.iotdb.confignode.rpc.thrift.TAuthizedPatternTreeResp;
@@ -481,6 +482,10 @@ public TSStatus checkUser(String username, String password) {
481482
return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
482483
} else if (password != null && AuthUtils.validatePassword(password, user.getPassword())) {
483484
return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
485+
} else if (password != null
486+
&& AuthUtils.validatePassword(
487+
password, user.getPassword(), AsymmetricEncrypt.DigestAlgorithm.MD5)) {
488+
return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
484489
} else {
485490
return RpcUtils.getStatus(TSStatusCode.WRONG_LOGIN_PASSWORD, "Authentication failed.");
486491
}

iotdb-core/datanode/src/test/java/org/apache/iotdb/db/security/encrypt/MessageDigestEncryptTest.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.iotdb.commons.conf.CommonDescriptor;
2626
import org.apache.iotdb.commons.exception.IllegalPathException;
2727
import org.apache.iotdb.commons.path.PartialPath;
28+
import org.apache.iotdb.commons.security.encrypt.AsymmetricEncrypt;
2829
import org.apache.iotdb.commons.security.encrypt.MessageDigestEncrypt;
2930
import org.apache.iotdb.db.utils.EnvironmentUtils;
3031
import org.apache.iotdb.db.utils.constant.TestConstant;
@@ -85,13 +86,20 @@ public void testMessageDigestEncrypt() throws AuthException, IllegalPathExceptio
8586
for (User user1 : users) {
8687
user = manager.getEntity(user1.getName());
8788
assertEquals(user1.getName(), user.getName());
88-
assertEquals(messageDigestEncrypt.encrypt(user1.getPassword()), user.getPassword());
89+
assertEquals(
90+
messageDigestEncrypt.encrypt(
91+
user1.getPassword(), AsymmetricEncrypt.DigestAlgorithm.SHA_256),
92+
user.getPassword());
8993
}
9094
}
9195

9296
@Test
9397
public void testMessageDigestValidatePassword() {
9498
String password = "root";
95-
assertTrue(messageDigestEncrypt.validate(password, messageDigestEncrypt.encrypt(password)));
99+
assertTrue(
100+
messageDigestEncrypt.validate(
101+
password,
102+
messageDigestEncrypt.encrypt(password, AsymmetricEncrypt.DigestAlgorithm.SHA_256),
103+
AsymmetricEncrypt.DigestAlgorithm.SHA_256));
96104
}
97105
}

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.iotdb.commons.conf.CommonDescriptor;
2929
import org.apache.iotdb.commons.exception.StartupException;
3030
import org.apache.iotdb.commons.path.PartialPath;
31+
import org.apache.iotdb.commons.security.encrypt.AsymmetricEncrypt;
3132
import org.apache.iotdb.commons.service.IService;
3233
import org.apache.iotdb.commons.service.ServiceType;
3334
import org.apache.iotdb.commons.utils.AuthUtils;
@@ -109,20 +110,43 @@ private void checkAdmin(String username, String errmsg) throws AuthException {
109110
@Override
110111
public boolean login(String username, String password) throws AuthException {
111112
User user = userManager.getEntity(username);
112-
return user != null
113-
&& password != null
114-
&& AuthUtils.validatePassword(password, user.getPassword());
113+
if (user == null || password == null) {
114+
return false;
115+
}
116+
if (AuthUtils.validatePassword(
117+
password, user.getPassword(), AsymmetricEncrypt.DigestAlgorithm.SHA_256)) {
118+
return true;
119+
}
120+
if (AuthUtils.validatePassword(
121+
password, user.getPassword(), AsymmetricEncrypt.DigestAlgorithm.MD5)) {
122+
userManager.updateUserPassword(username, password);
123+
return true;
124+
}
125+
return false;
115126
}
116127

117128
@Override
118129
public String login4Pipe(final String username, final String password) {
119130
final User user = userManager.getEntity(username);
120-
return (user != null
121-
&& password != null
122-
&& AuthUtils.validatePassword(password, user.getPassword())
123-
|| Objects.isNull(password))
124-
? user.getPassword()
125-
: null;
131+
if (Objects.isNull(password)) {
132+
return user.getPassword();
133+
}
134+
if (user == null) {
135+
return null;
136+
}
137+
if (AuthUtils.validatePassword(
138+
password, user.getPassword(), AsymmetricEncrypt.DigestAlgorithm.SHA_256)) {
139+
return user.getPassword();
140+
}
141+
if (AuthUtils.validatePassword(
142+
password, user.getPassword(), AsymmetricEncrypt.DigestAlgorithm.MD5)) {
143+
try {
144+
userManager.updateUserPassword(username, password);
145+
} catch (AuthException ignore) {
146+
}
147+
return userManager.getEntity(username).getPassword();
148+
}
149+
return null;
126150
}
127151

128152
@Override

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/AsymmetricEncrypt.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@
2121

2222
public interface AsymmetricEncrypt {
2323

24+
/**
25+
* Defines cryptographic hash algorithms supported by the system. Each enum constant represents a
26+
* specific message digest algorithm compatible with {@link java.security.MessageDigest}.
27+
*/
28+
enum DigestAlgorithm {
29+
MD5("MD5"),
30+
SHA_256("SHA-256");
31+
32+
private final String algorithmName;
33+
34+
DigestAlgorithm(String algorithmName) {
35+
this.algorithmName = algorithmName;
36+
}
37+
38+
public String getAlgorithmName() {
39+
return this.algorithmName;
40+
}
41+
}
42+
2443
/**
2544
* init some providerParameter
2645
*
@@ -34,7 +53,7 @@ public interface AsymmetricEncrypt {
3453
* @param originPassword password to be crypt
3554
* @return encrypt password
3655
*/
37-
String encrypt(String originPassword);
56+
String encrypt(String originPassword, DigestAlgorithm digestAlgorithm);
3857

3958
/**
4059
* validate originPassword and encryptPassword
@@ -43,5 +62,5 @@ public interface AsymmetricEncrypt {
4362
* @param encryptPassword encrypt password
4463
* @return true if validate success
4564
*/
46-
boolean validate(String originPassword, String encryptPassword);
65+
boolean validate(String originPassword, String encryptPassword, DigestAlgorithm digestAlgorithm);
4766
}

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/security/encrypt/MessageDigestEncrypt.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,15 @@
2929
public class MessageDigestEncrypt implements AsymmetricEncrypt {
3030
private static final Logger logger = LoggerFactory.getLogger(MessageDigestEncrypt.class);
3131

32-
private static final String ENCRYPT_ALGORITHM = "MD5";
3332
private static final String STRING_ENCODING = "utf-8";
3433

3534
@Override
3635
public void init(String providerParameters) {}
3736

3837
@Override
39-
public String encrypt(String originPassword) {
38+
public String encrypt(String originPassword, DigestAlgorithm digestAlgorithm) {
4039
try {
41-
MessageDigest messageDigest = MessageDigest.getInstance(ENCRYPT_ALGORITHM);
40+
MessageDigest messageDigest = MessageDigest.getInstance(digestAlgorithm.getAlgorithmName());
4241
messageDigest.update(originPassword.getBytes(STRING_ENCODING));
4342
return new String(messageDigest.digest(), STRING_ENCODING);
4443
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
@@ -48,10 +47,11 @@ public String encrypt(String originPassword) {
4847
}
4948

5049
@Override
51-
public boolean validate(String originPassword, String encryptPassword) {
50+
public boolean validate(
51+
String originPassword, String encryptPassword, DigestAlgorithm digestAlgorithm) {
5252
if (originPassword == null) {
5353
return false;
5454
}
55-
return encrypt(originPassword).equals(encryptPassword);
55+
return encrypt(originPassword, digestAlgorithm).equals(encryptPassword);
5656
}
5757
}

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/AuthUtils.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.iotdb.commons.path.PartialPath;
2727
import org.apache.iotdb.commons.path.PathDeserializeUtil;
2828
import org.apache.iotdb.commons.path.PathPatternUtil;
29+
import org.apache.iotdb.commons.security.encrypt.AsymmetricEncrypt;
2930
import org.apache.iotdb.commons.security.encrypt.AsymmetricEncryptFactory;
3031
import org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp;
3132
import org.apache.iotdb.confignode.rpc.thrift.TRoleResp;
@@ -81,7 +82,24 @@ public static boolean validatePassword(String originPassword, String encryptPass
8182
return AsymmetricEncryptFactory.getEncryptProvider(
8283
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProvider(),
8384
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProviderParameter())
84-
.validate(originPassword, encryptPassword);
85+
.validate(originPassword, encryptPassword, AsymmetricEncrypt.DigestAlgorithm.SHA_256);
86+
}
87+
88+
/**
89+
* Checking whether origin password is mapping to encrypt password by encryption
90+
*
91+
* @param originPassword the password before encryption
92+
* @param encryptPassword the password after encryption
93+
* @param digestAlgorithm the algorithm for encryption
94+
*/
95+
public static boolean validatePassword(
96+
String originPassword,
97+
String encryptPassword,
98+
AsymmetricEncrypt.DigestAlgorithm digestAlgorithm) {
99+
return AsymmetricEncryptFactory.getEncryptProvider(
100+
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProvider(),
101+
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProviderParameter())
102+
.validate(originPassword, encryptPassword, digestAlgorithm);
85103
}
86104

87105
/**
@@ -171,7 +189,7 @@ public static String encryptPassword(String password) {
171189
return AsymmetricEncryptFactory.getEncryptProvider(
172190
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProvider(),
173191
CommonDescriptor.getInstance().getConfig().getEncryptDecryptProviderParameter())
174-
.encrypt(password);
192+
.encrypt(password, AsymmetricEncrypt.DigestAlgorithm.SHA_256);
175193
}
176194

177195
/**

0 commit comments

Comments
 (0)