【问题标题】:Hashed passwords updated through JDBC become corrupt. (More of encoding problem than hashing)通过 JDBC 更新的散列密码损坏。 (比散列更多的编码问题)
【发布时间】:2010-10-07 07:35:10
【问题描述】:

我已尝试使用 MySQL UTF-8 和 Latin-1 进行以下操作,但无济于事。

我使用 SHA-1 散列我的密码(在本例中为 toSecurify),如下所示:

  if(toSecurify == null) {
   throw new Exception("toSecurifyString must not be null");
  }
  try {
   MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
   byte[] sha1HashBytes = new byte[40];
   messageDigest.update(toSecurify.getBytes(), 0, toSecurify.length());
   sha1HashBytes = messageDigest.digest();
   return new String(sha1HashBytes, "UTF-8");
  } catch(NoSuchAlgorithmException nsae) {
   throw new Exception("Hash algorithm not supported.");
  } catch(UnsupportedEncodingException uee) {
   throw new Exception("Encoding not supported.");
  }

然后我将其存储在 mysql 数据库密码列中。

现在这是我可以查询数据库的棘手部分: 有没有记录

username=<insertUserName> and password = thatHashFunctionUpThere(<insertPassword>);

这很好用。

但是现在,更新记录看起来像这样:

String userName = someJdbcStuffToGetUsername();
String password = someJdbcStuffToGetPassword();

update(userName, password);

密码现已更改!这会破坏密码。 就像在出路时(查询时)它被破坏了,但从来没有在路上。 我这样说是因为插入和查询工作得很好,但是当我取出值然后再次设置它时,它会破坏它,所以它必须在路上。

有人有什么想法吗? 我应该在哪里寻找编码问题?

提前谢谢各位!

【问题讨论】:

  • 您是否在更新时错误地重新散列了已经散列的密码?
  • 史蒂夫的建议不错,但不,我不是。 :|
  • 澄清一下:更新后读取不再起作用? IE。密码已在数据库中更改,而不仅仅是在您的更新代码中?
  • 好吧,您可以读取该行,但是数据库中的密码已损坏,这意味着他们无法登录。所以我认为正在发生的事情正在进行中(正在读取)它被损坏了,然后我在更新它们时将损坏的值放回用户。
  • 似乎不太可能是数据库问题,更有可能是代码。两个建议: 1)调试代码并查看从数据库中检索到的值在更新方法中是否正确,如果正确,则更改位置。 2) 使用 mySQL 客户端进行插入/读取/更新设置,看看是否有效

标签: java mysql jdbc sha1


【解决方案1】:

你的代码有缺陷。

return new String(sha1HashBytes, "UTF-8"); 

您不应该将字节视为字符。实际上,您应该将每个字节转换为 2 个字符的十六进制字符串。例如

StringBuilder hex = new StringBuilder(sha1HashBytes.length * 2);
for (byte b : sha1HashBytes) {
    if ((b & 0xff) < 0x10) hex.append("0");
    hex.append(Integer.toHexString(b & 0xff));
}
return hex.toString();

但是,最好只使用 MySQL 自己的 SHA1() 函数。在INSERT 上做:

String sql = "INSERT INTO user (username, password) VALUES (?, SHA1(?))";
// ...
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(username);
preparedStatement.setString(password); // This one should be unhashed!!
int affectedRows = preparedStatement.executeUpdate();
// ...

UPDATE:

String sql = "UPDATE user SET username = ?, password = SHA1(?) WHERE id = ?";
// ...
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(username);
preparedStatement.setString(password); // This one should be unhashed!!
preparedStatement.setLong(id);
int affectedRows = preparedStatement.executeUpdate();
// ...

SELECT:

String sql = "SELECT * FROM user WHERE username = ? AND password = SHA1(?)";
// ...
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(username);
preparedStatement.setString(password); // This one should be unhashed!!
resultSet = preparedStatement.executeQuery();
// ...

另见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    • 2020-12-20
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2015-02-09
    相关资源
    最近更新 更多