让人没有想到,H2 支持对数据库文件进行加密,这样一定程度上提供了更安全的支持。H2 支持三种加密算法:
AES,也称为 Rijndael,仅实现了 AES-128。
XTEA,32 轮版本。
FOG,伪加密,仅适用于隐藏文本编辑器中的数据。有点类似 Base64,仅是数据编码。
注意:要使用文件加密,需要在连接数据库时指定加密算法(密码)和文件密码(除用户密码外)。
默认情况下,使用嵌入式 URL 时,如果新数据库尚未存在,则会自动创建。要创建加密数据库,请使用嵌入式 URL 连接到本地已存在的数据库。例如:
// 使用加密数据库,文件密码为:123abc,用户密码为:aaaaaa Connection connection = DriverManager.getConnection( "jdbc:h2:~/test-aes;CIPHER=AES", "sa", "123abc aaaaaa");
加密算法在数据库 URL 中设置,文件密码在用户密码之前的密码字段中指定。文件密码和用户密码之间用一个空格隔开,文件密码本身不得包含空格。文件密码和用户密码区分大小写。
下面是一个连接到密码加密数据库的示例:
{ // 使用加密数据库,文件密码为:123abc,用户密码为:aaaaaa Connection connection = DriverManager.getConnection("jdbc:h2:~/test-aes;CIPHER=AES", "sa", "123abc aaaaaa"); Statement statement = connection.createStatement(); statement.execute("CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY, name VARCHAR(255))"); statement.execute("TRUNCATE TABLE users"); // 清空表 statement.execute("INSERT INTO users VALUES (1, '张三')"); // 插入一条数据 // 查询数据 ResultSet resultSet = statement.executeQuery("SELECT * FROM users"); while(resultSet.next()) { System.out.println(resultSet.getInt("id") + " - " + resultSet.getString("name")); } statement.close(); connection.close(); } // 尝试使用错误的密码访问数据库,错误如下: // org.h2.jdbc.JdbcSQLInvalidAuthorizationSpecException: Wrong user name or password [28000-232] DriverManager.getConnection("jdbc:h2:~/test-aes;CIPHER=AES", "sa", "123abc aaabbb");
要加密现有数据库,请使用 ChangeFileEncryption 工具。该工具还可以解密已加密的数据库,或更改文件加密密钥。该工具可从 H2 控制台的工具部分获取,也可从命令行运行。
以下命令行将使用文件密码 filepwd 和加密算法 AES 加密用户主目录下的数据库 test:
java -cp h2*.jar org.h2.tools.ChangeFileEncryption -dir ~ -db test -cipher AES -encrypt filepwd