-1

好的,所以我正在尝试为我的一个小型 Java 项目创建用户身份验证,但我遇到了一些障碍。我有一个名为 user_info 的表,有 3 列;id、用户名和密码。

我意识到我可能应该有某种形式的加密,所以我使用 Java 的 MessageDigest 用 SHA1 加密密码。由于我还没有供人们注册的网站(并让 PHP 将加密的 PW 输入数据库),我只是加密了一个测试密码,并将数据库中未加密的密码替换为加密的密码。

例如,用户名 test 和密码 test 的用户的加密密码为:895df4f75b316de68d167ed2e83adb0bedbbde17

所以我的数据库有一个 id 为 0、用户 test 和密码为 895df4f75b316de68d167ed2e83adb0bedbbde17 的条目。

现在,在我开始使用加密密码之前,我的 Java 代码用于检查提供有效详细信息的人是否没有问题。

这是我的 Java 应用程序的登录代码:

public int doLogin(String username, String pass) {
    EncryptionHandler e = new EncryptionHandler();

    String userToLogIn = username;
    String userToLogInPassword = pass;

    try {
        String fixedUser = prepString(userToLogIn);
        String fixedPass = e.doEncryptPassword(prepString(userToLogInPassword));
        System.out.println(fixedPass);

        con = DriverManager.getConnection(url, user, password);
        st = con.createStatement();
        rs = st.executeQuery("SELECT * FROM `user_info` WHERE `user` = " + fixedUser + " AND `password` = " + fixedPass);

        if (rs.next()) {
            //System.out.println("ID: " + rs.getString(1) + ", USER: " + rs.getString(2) + ", PASSWORD: " + rs.getString(3));
            return 1;
        } else {
            System.out.println("Username or password is invalid!");
            return 0;
        }

    } catch (SQLException ex) {
        System.out.println(ex.getMessage());
    } finally {
        try {
            if (rs != null) {
                rs.close();
            }
            if (st != null) {
                st.close();
            }
            if (con != null) {
                con.close();
            }

        } catch (SQLException ex) {
        }
    }
    return 0;
}

private String prepString(String s) {
    return new StringBuilder().append("'").append(s).append("'").toString();
}

如果需要,我的加密方法:

public String doEncryptPassword(String s) {
    MessageDigest sha1;
    try {
        sha1 = MessageDigest.getInstance("SHA1");
        byte[] digest = sha1.digest((s).getBytes());
        return bytes2String(digest);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

    return s;

}
private static String bytes2String(byte[] bytes) {
    StringBuilder string = new StringBuilder();
    for (byte b : bytes) {
        String hexString = Integer.toHexString(0x00FF & b);
        string.append(hexString.length() == 1 ? "0" + hexString : hexString);
    }
    return string.toString();
}

同样,使用未加密的密码可以正常工作,但是一旦我加密密码,我就会收到未知列错误。在这个例子中(用户测试,密码测试),通过未加密的密码没有收到错误,但是使用加密的密码 895df4f75b316de68d167ed2e83adb0bedbbde17 给我提供了错误:'where 子句'中的未知列'895df4f75b316de68d167ed2e83adb0bedbbde17'

4

2 回答 2

2

Ignoring that this isn't encryption, you have invalid SQL because of quoting problems. As @Leigh notes in the comments, you put quotes at the beginning and end of your password string ... then hash it. Your quotes are now dearly departed.

Of course you should never create SQL like this in the first place. Use prepared statements -> Oracle Prepared Statements Tutorial

Get rid of any of your own home-grown string quoting then simply do:

String sqlString = "SELECT * FROM user_info WHERE user = ? AND password = ?";
PreparedStatement ps = con.prepareStatement(sqlString);
ps.setString(1, username);
ps.setString(2, hashedPassword);
ResultSet rs = ps.executeQuery();
于 2013-08-09T20:41:54.220 回答
1

您还需要为密码执行 prepString 操作:

    String fixedPass = prepString(e.doEncryptPassword(userToLogInPassword));

But it isn't a good idea to build statements this way. Use prepared statements.

于 2013-08-09T20:31:55.263 回答