提交 b02f0a5a authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Convert cleartext passwords to hashes with salt

上级 64a778cc
...@@ -406,9 +406,9 @@ public class WebApp { ...@@ -406,9 +406,9 @@ public class WebApp {
boolean ssl = Utils.parseBoolean((String) attributes.get("ssl"), false, false); boolean ssl = Utils.parseBoolean((String) attributes.get("ssl"), false, false);
prop.setProperty("webSSL", String.valueOf(ssl)); prop.setProperty("webSSL", String.valueOf(ssl));
server.setSSL(ssl); server.setSSL(ssl);
String adminPassword = server.getAdminPassword(); byte[] adminPassword = server.getAdminPassword();
if (adminPassword != null && !adminPassword.isEmpty()) { if (adminPassword != null) {
prop.setProperty("adminPassword", adminPassword); prop.setProperty("adminPassword", StringUtils.convertBytesToHex(adminPassword));
} }
server.saveProperties(prop); server.saveProperties(prop);
} catch (Exception e) { } catch (Exception e) {
......
...@@ -16,6 +16,7 @@ import java.sql.Connection; ...@@ -16,6 +16,7 @@ import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
...@@ -28,6 +29,7 @@ import java.util.Set; ...@@ -28,6 +29,7 @@ import java.util.Set;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.security.SHA256;
import org.h2.server.Service; import org.h2.server.Service;
import org.h2.server.ShutdownHandler; import org.h2.server.ShutdownHandler;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
...@@ -154,7 +156,7 @@ public class WebServer implements Service { ...@@ -154,7 +156,7 @@ public class WebServer implements Service {
private final Set<WebThread> running = private final Set<WebThread> running =
Collections.synchronizedSet(new HashSet<WebThread>()); Collections.synchronizedSet(new HashSet<WebThread>());
private boolean ssl; private boolean ssl;
private String adminPassword; private byte[] adminPassword;
private final HashMap<String, ConnectionInfo> connInfoMap = new HashMap<>(); private final HashMap<String, ConnectionInfo> connInfoMap = new HashMap<>();
private long lastTimeoutCheck; private long lastTimeoutCheck;
...@@ -279,7 +281,7 @@ public class WebServer implements Service { ...@@ -279,7 +281,7 @@ public class WebServer implements Service {
"webSSL", false); "webSSL", false);
allowOthers = SortedProperties.getBooleanProperty(prop, allowOthers = SortedProperties.getBooleanProperty(prop,
"webAllowOthers", false); "webAllowOthers", false);
adminPassword = SortedProperties.getStringProperty(prop, "adminPassword", null); setAdminPassword(SortedProperties.getStringProperty(prop, "adminPassword", null));
commandHistoryString = prop.getProperty(COMMAND_HISTORY); commandHistoryString = prop.getProperty(COMMAND_HISTORY);
for (int i = 0; args != null && i < args.length; i++) { for (int i = 0; args != null && i < args.length; i++) {
String a = args[i]; String a = args[i];
...@@ -299,7 +301,7 @@ public class WebServer implements Service { ...@@ -299,7 +301,7 @@ public class WebServer implements Service {
} else if (Tool.isOption(a, "-ifNotExists")) { } else if (Tool.isOption(a, "-ifNotExists")) {
ifExists = false; ifExists = false;
} else if (Tool.isOption(a, "-adminPassword")) { } else if (Tool.isOption(a, "-adminPassword")) {
adminPassword = args[++i]; setAdminPassword(args[++i]);
} else if (Tool.isOption(a, "-properties")) { } else if (Tool.isOption(a, "-properties")) {
// already set // already set
i++; i++;
...@@ -683,8 +685,8 @@ public class WebServer implements Service { ...@@ -683,8 +685,8 @@ public class WebServer implements Service {
Boolean.toString(SortedProperties.getBooleanProperty(old, "webAllowOthers", allowOthers))); Boolean.toString(SortedProperties.getBooleanProperty(old, "webAllowOthers", allowOthers)));
prop.setProperty("webSSL", prop.setProperty("webSSL",
Boolean.toString(SortedProperties.getBooleanProperty(old, "webSSL", ssl))); Boolean.toString(SortedProperties.getBooleanProperty(old, "webSSL", ssl)));
if (adminPassword != null && !adminPassword.isEmpty()) { if (adminPassword != null) {
prop.setProperty("adminPassword", adminPassword); prop.setProperty("adminPassword", StringUtils.convertBytesToHex(adminPassword));
} }
if (commandHistoryString != null) { if (commandHistoryString != null) {
prop.setProperty(COMMAND_HISTORY, commandHistoryString); prop.setProperty(COMMAND_HISTORY, commandHistoryString);
...@@ -855,15 +857,36 @@ public class WebServer implements Service { ...@@ -855,15 +857,36 @@ public class WebServer implements Service {
return allowChunked; return allowChunked;
} }
String getAdminPassword() { byte[] getAdminPassword() {
return adminPassword; return adminPassword;
} }
void setAdminPassword(String password) {
if (password == null || password.isEmpty()) {
adminPassword = null;
return;
}
if (password.length() == 128) {
try {
adminPassword = StringUtils.convertHexToBytes(password);
return;
} catch (Exception ex) {}
}
byte[] salt = MathUtils.secureRandomBytes(32);
byte[] hash = SHA256.getHashWithSalt(password.getBytes(StandardCharsets.UTF_8), salt);
byte[] total = Arrays.copyOf(salt, 64);
System.arraycopy(hash, 0, total, 32, 32);
adminPassword = total;
}
boolean checkAdminPassword(String password) { boolean checkAdminPassword(String password) {
if (adminPassword == null) { if (adminPassword == null) {
return false; return false;
} }
return adminPassword.equals(password); byte[] salt = Arrays.copyOf(adminPassword, 32);
byte[] hash = new byte[32];
System.arraycopy(adminPassword, 32, hash, 0, 32);
return Utils.compareSecure(hash, SHA256.getHashWithSalt(password.getBytes(StandardCharsets.UTF_8), salt));
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论