-1

私の小さなJavaプロジェクトのユーザー認証を作成しようとしていますが、ちょっとした障害に遭遇しました。3 つの列を持つ user_info というテーブルがあります。ID、ユーザー、パスワード。

おそらく何らかの形式の暗号化が必要であることに気付いたので、Java の MessageDigest を使用して SHA1 でパスワードを暗号化しました。私はまだ人々が登録するための Web サイトを持っていないので (そして 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 を使用すると、エラーが表示されます。

4

2 に答える 2

2

これが暗号化ではないことを無視すると、引用の問題のために無効な SQL が発生します。コメントで@Leighが指摘しているように、パスワード文字列の最初と最後に引用符を付けてからハッシュします。あなたの引用は今、心から離れています。

もちろん、そもそもこのような SQL を作成するべきではありません。プリペアド ステートメントを使用する -> Oracle プリペアド ステートメント チュートリアル

独自の独自の文字列引用符を削除してから、次のようにします。

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 に答える