加密密码导致'where子句'中的MySQL未知列

时间:2013-08-09 20:25:21

标签: java mysql

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

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

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

所以我的数据库有一个id为0的条目,用户测试和密码为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'

2 个答案:

答案 0 :(得分:2)

忽略这不是加密,因为引用问题而导致SQL无效。正如@Leigh在评论中指出的那样,你在密码字符串的开头和结尾加上引号......然后哈希吧。你的报价现已离开了。

当然,您应该从不首先创建这样的SQL 。使用准备好的陈述 - > Oracle Prepared Statements Tutorial

摆脱任何你自己的本土字符串引用然后只需:

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();

答案 1 :(得分:1)

您还需要为密码执行prepString,

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

但以这种方式构建语句不是一个好主意。 使用准备好的陈述。