【问题标题】:GlassFish SHA-256 digest authenticationGlassFish SHA-256 摘要认证
【发布时间】:2011-10-15 09:21:27
【问题描述】:

出于开发目的,我一直以纯文本形式存储我的密码,但我想开始存储哈希值,但由于以下 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 Security - jdbcRealm: How to configure login with SHA-256 digest 建议您确实需要这样做。

所以我想我想知道的是,GlassFish 是否期望将字符串 (VARCHAR) 或字节 [] (BLOB) 作为数据库中的密码字段,我是否正确地对密码进行哈希处理,是否正确另外Base64编码密码哈希?

谢谢!

【问题讨论】:

    标签: java jakarta-ee jdbc glassfish sha256


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

    • 再次感谢!原来我确实没有在 JDBC 领域指定编码参数,现在它可以正常工作了!
    • @Laurens,嗯,我在几周前曾与同样的野兽打过仗,所以您不必经历所有麻烦。无论如何,该项目的源代码将在几天内提供,因此您将能够看到一个有效的实现,而不是阅读我的答案。
    • 很高兴听到,期待!
    猜你喜欢
    • 1970-01-01
    • 2011-03-27
    • 2015-06-18
    • 2012-12-31
    • 2011-03-02
    • 2013-08-29
    • 1970-01-01
    • 2012-07-18
    • 2015-01-04
    相关资源
    最近更新 更多