请记住,无论采用何种加密和安全协议,弱密码都有可能被破解,不要使用可以在字典中找到的密码。
Java 字符串是不可变对象,应用程序无法安全地将其“销毁”。创建字符串后,它至少会保留在计算机的主内存中,直到被垃圾回收。应用程序无法控制垃圾回收,即使进行了垃圾回收,数据仍可能保留在内存中。如果攻击者可以访问操作系统的交换文件,那么包含密码的内存部分就有可能被交换到磁盘上(如果没有足够的主内存可用)。
密码最好使用字符数组而不是字符串。字符数组在使用后可以被清除(填充 0),因此密码不会存储在交换文件中。
本数据库支持使用字符数组而不是字符串来传递用户和文件密码。例如:
import java.sql.*; import java.util.*; public class Test { public static void main(String[] args) throws Exception { String url = "jdbc:h2:~/test"; Properties prop = new Properties(); prop.setProperty("user", "sa"); System.out.print("Password?"); char[] password = System.console().readPassword(); prop.put("password", password); Connection conn = null; try { conn = DriverManager.getConnection(url, prop); } finally { Arrays.fill(password, (char) 0); } conn.close(); } }
注意:使用 Swing 编程时,使用 javax.swing.JPassword 组件。
在 JDBC 中,我们通过 DriverManager.getConnection 获取 H2 数据库连接,在获取连接时,我们通过方法参数将密码传递给 H2,例如:
Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "123");
注意,用户名(和/或密码)可以直接在 URL 本身中提供,而不是在 DriverManager.getConnection() 方法中通过参数提供,例如:
Connection conn = DriverManager.getConnection("jdbc:h2:~/test;USER=sa;PASSWORD=123");
注意: URL 中的设置覆盖作为单独参数传递的设置。
有时,数据库密码需要存储在配置文件(如 web.xml 文件)中。除了使用纯文本密码连接外,该数据库还支持使用密码哈希值连接。这意味着配置文件中只需存储密码的哈希值(而非纯文本密码)。这只能防止他人读取或重新构造纯文本密码(即使他们能访问配置文件),但不能防止他人使用密码散列访问数据库。
要使用密码散列而不是纯文本密码进行连接,请在数据库 URL 中添加 ;PASSWORD_HASH=TRUE 并用密码散列替换密码。要根据纯文本密码计算密码散列,请在 H2 控制台工具中运行以下命令: @password_hash <大写用户名> <密码>。例如,如果用户名是 sa,密码是 test,则运行 @password_hash SA test 命令。然后像使用纯文本密码一样使用生成的密码散列。使用加密数据库时,用户密码和文件密码需要分别散列。要计算文件密码的哈希值,请运行 @password_hash file <filePassword>.