GlassFish SHA-256 摘要身份验证

发布于 2024-11-27 02:55:42 字数 1534 浏览 3 评论 0原文

出于开发目的,我一直以纯文本形式存储密码,但想开始存储哈希值,但由于出现以下 SecurityException,到目前为止尚未成功让 GlassFish 针对哈希密码进行正确身份验证:

SEVERE: jdbcrealm.invaliduserreason
WARNING: WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Security Exception

首先,我正在运行GlassFish 3.1 并将我的 JDBC 领域的摘要设置为 SHA-256。

我的 User 类具有以下带注释的密码字段:

@Basic(fetch = FetchType.LAZY)
@Column(length = 45, nullable = false)
private String password;

以下帮助器方法负责对密码进行哈希处理:

private byte[] digest(String input) {
    byte[] output = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        output = md.digest(input.getBytes("UTF-8"));
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(RegistrationController.class.getName()).log(Level.SEVERE, null, ex);
    } catch (UnsupportedEncodingException ex) {
        Logger.getLogger(RegistrationController.class.getName()).log(Level.SEVERE, null, ex);
    }
    return output;
}

然后我按如下方式设置用户的密码:

u.setPassword(Base64.encode(digest(password)).toString());

我不会对 Base64 进行编码,因为这似乎没有记录,但这个问题:Glassfish 安全 - jdbcRealm:如何使用 SHA 配置登录 - 256摘要建议您确实需要这样做。

所以我想我想知道的是,GlassFish 是否期望 String (VARCHAR) 或 byte[] (BLOB) 作为数据库中的密码字段,我是否正确地散列密码,以及附加 Base64 编码是否正确密码哈希?

谢谢!

I have been storing my passwords in plain-text for development purposes but want to start storing the hashes instead, but have so far not yet succeeded in having GlassFish properly authenticate against a hashed password due to the following SecurityException:

SEVERE: jdbcrealm.invaliduserreason
WARNING: WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Security Exception

First off, I am running GlassFish 3.1 and have setup the digest for my JDBC realm to SHA-256.

My User class has the following annotated password field:

@Basic(fetch = FetchType.LAZY)
@Column(length = 45, nullable = false)
private String password;

The following helper method is responsible for hashing the password:

private byte[] digest(String input) {
    byte[] output = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        output = md.digest(input.getBytes("UTF-8"));
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(RegistrationController.class.getName()).log(Level.SEVERE, null, ex);
    } catch (UnsupportedEncodingException ex) {
        Logger.getLogger(RegistrationController.class.getName()).log(Level.SEVERE, null, ex);
    }
    return output;
}

I then set the password on the user as follows:

u.setPassword(Base64.encode(digest(password)).toString());

I wouldn't have Base64 encoded the because this seems to be undocumented but this question: Glassfish Security - jdbcRealm: How to configure login with SHA-256 digest suggests you do need to do so.

So I guess what I would like to know is, does GlassFish expect a String (VARCHAR) or a byte[] (BLOB) as the password field in the database, am I correctly hashing the password, and is it correct to additionally Base64 encode the password hash?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青萝楚歌 2024-12-04 02:55:42

GlassFish 是否需要字符串 (VARCHAR) 或 byte[] (BLOB) 作为数据库中的密码字段?

它需要一个映射到 JDBC 中的 Java 类型 java.lang.String 的列,这些列通常是 CHAR、VARCHAR 等。LOB 将无法工作,因为 JDBC 领域实现会发出 ResultSet .getString 方法调用调用来获取密码哈希值。

我是否正确地对密码进行了哈希处理,另外对密码哈希进行 Base64 编码是否正确?

Base64 编码不是唯一受支持的选项。您也可以执行十六进制编码。但您必须执行其中任何一个,并将 JDBC 领域配置为在运行时执行相同的操作。如果没有编码参数,Glassfish 会将与摘要关联的字节序列转换为为领域配置的 charset 中的字符序列。

我怀疑这个问题与表达式 input.getBytes("UTF-8") 中提到的 UTF-8 编码有关。值得验证 digest 方法提供的结果的 Base64 编码是否确实与数据库中存储的密码哈希相匹配。

另外,考虑到失败的原因是jdbcrealm.invaliduserreason,我还怀疑以下条件之一可能为真:

  • 未为 JDBC Realm 指定编码参数;它最好是 base64hex 之一(大小写并不重要,根据 JDBC 领域的源代码),否则您最终会遇到以下情况:摘要字节数组被转换为字符数组(在我看来,这有点不稳定,除非你能保证用户提供的密码始终采用特定的编码)。
  • 数据库中不存在该用户的密码哈希。请参阅我之前关于执行的 SQL 查询的答案;您可能想自己运行查询。您可以记录 Derby 发出的语句(如果您将其用作数据库),方法是将名为 derby.properties 的文件放置在 Derby 数据库的位置,其属性为 derby.language.logStatementText=true 其中。关闭数据库时,derby.log 文件将填充应用程序服务器发出的所有查询。
  • Glassfish 准备的 SQL 语句不正确。
  • 无法建立与数据库的连接。

Does GlassFish expect a String (VARCHAR) or a byte[] (BLOB) as the password field in the database?

It expects a column that maps to the Java Type java.lang.String in JDBC, and those would typically be CHAR, VARCHAR etc. LOBs would not work as the JDBC realm implementation issues a ResultSet.getString method call invocation to obtain the password hash.

Am I correctly hashing the password, and is it correct to additionally Base64 encode the password hash?

Base64 encoding is not the only supported option. You can perform Hex encoding as well. But you must perform either of these, and configure the JDBC Realm to perform the same at runtime. In the absence of an encoding parameter, Glassfish will convert the byte sequence associated with the digest, to a sequence of characters in the charset configured for the realm.

I suspect the problem has something to do with the mention of UTF-8 encoding in the expression input.getBytes("UTF-8"). It would be worth verifying if the Base64 encoding of the result provided by your digest method actually matches the password hashes stored in the database.

Also, considering the reason provided for the failure being jdbcrealm.invaliduserreason, I would also suspect that one of the following conditions might be true:

  • The encoding parameter is not specified for the JDBC Realm; it should preferably be one of base64 or hex (the case does not matter, going by the source code of the JDBC realm), otherwise you would end up in the scenario where the digest byte array is converted to a character array (which in my opinion is a bit flaky unless you can guarantee that the password provided by users are always in a particular encoding).
  • No password hash exists for the user in the database. See my previous answer on the SQL query executed; you might want to run the query yourself. You can log the statements issued by Derby (if you are using it as the database), by placing a file named derby.properties in the location of your Derby database with the property derby.language.logStatementText=true in it. On shutting down the database, the derby.log file will be populated with all the queries issued by the application server.
  • The SQL statement prepared by Glassfish is incorrect.
  • A connection to the database could not be established.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文