Java 保存到 SQL 后 Byte[] 数据发生变化

Byte[] data changes after saved to SQL with Java

 public void saveNewAccount(String name, String username, byte[] pas, byte [] salt) {
    try {
        Class.forName(myUrl);
        c = DriverManager.getConnection(myDriver);
        c.setAutoCommit(false);
        stmt = c.createStatement();
        System.out.println(Arrays.toString(pas)+ "before save");
        String sql = "INSERT INTO accounts (NAME, USERNAME, PASSWORD, PASSWORDSALT) " +
                "VALUES ('"+name+"','"+username+"','"+pas+"','"+salt+"');";
        stmt.executeUpdate(sql);
        stmt.close();
        c.commit();
        c.close();
    } catch ( Exception e ) {
        System.err.println( e.getClass().getName() + ": " + e.getMessage() );
        System.exit(0);
    }
}

public List<byte[]> getAccountPas(String username) {
    List<byte[]> acc = null;
    try {
        acc = new ArrayList<>();
        Class.forName(myUrl);
        c = DriverManager.getConnection(myDriver);
        c.setAutoCommit(false);
        stmt = c.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM accounts WHERE (USERNAME='"+username+"');");
        while (rs.next()) {
            acc.add(rs.getBytes("PASSWORDSALT"));
            acc.add(rs.getBytes("PASSWORD"));
            System.out.println(Arrays.toString(acc.get(0))+ "salt sql");
            System.out.println(Arrays.toString(acc.get(1)) + "pas from sql");
        }
        stmt.close();
        c.commit();
        c.close();
    } catch (Exception e) {
        System.err.println(e.getClass().getName() + ": " + e.getMessage());
        System.exit(0);
    }
    return acc;
}

所以我这里有问题。 从数据库中获取密码后,它与我保存的版本不同。 但是盐还是一样的。 我今天花时间弄清楚,但找不到解决方案。 感谢所有愿意提供帮助的人。 :)

我注意到您在两个查询的最后都有一个分号 ;,请尝试像这样删除它们:

  "INSERT INTO...."'"
  "SELECT * FROM ..."'"

不要 使用字符串连接来使用来自外部源(例如用户)的值构建 SQL 语句。如果值包含 ',SQL 语句将失败并出现语法错误,或者更糟的是,代码只是要求使用 SQL Injection 进行黑客攻击,允许黑客窃取您的数据 and/or 删除你的表。

至于您遇到的问题,当然数据库不包含您尝试保存的值。像 passalt 这样的字节数组在与字符串连接时会是这样的:

[B@659e0bfd

所以你SQL是:

INSERT INTO accounts (NAME, USERNAME, PASSWORD, PASSWORDSALT)
VALUES ('John Doe','jdoe','[B@2a139a55','[B@659e0bfd');

上面提到的两个问题(SQL注入和字节数组)的解决方法是一样的:使用PreparedStatement.

注意:删除 SQL 语句末尾无关的 ;。不要以 ; 结束 SQL 语句。还更改为使用 try-with-resources,以实现更好的资源清理处理。

public void saveNewAccount(String name, String username, byte[] pas, byte [] salt) {
    try (Connection c = DriverManager.getConnection("")) {
        c.setAutoCommit(false);
        String sql = "INSERT INTO accounts (NAME, USERNAME, PASSWORD, PASSWORDSALT)" +
                    " VALUES (?,?,?,?)";
        try (PreparedStatement stmt = c.prepareStatement(sql)) {
            stmt.setString(1, name);
            stmt.setString(2, username);
            stmt.setBytes (3, pas);
            stmt.setBytes (4, salt);
            stmt.executeUpdate();
            c.commit();
        } catch (Exception e) {
            c.rollback();
            throw e;
        }
    } catch (Exception e) {
        System.err.println(e.getClass().getName() + ": " + e.getMessage());
        System.exit(0);
    }
}