我出于开发目的一直以纯文本形式存储密码,但想开始存储哈希值,但由于以下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是否期望将String(VARCHAR)或byte [](BLOB)作为数据库中的密码字段,我是否正确地对密码进行了哈希处理,并且另外进行Base64编码是否正确?密码哈希?
谢谢!
最佳答案
GlassFish是否期望将String(VARCHAR)或byte [](BLOB)作为数据库中的密码字段?
它需要一个映射到JDBC中Java类型java.lang.String
的列,而这些列通常是CHAR,VARCHAR等。LOB将不起作用,因为JDBC领域实现发出ResultSet.getString
方法调用调用来获取密码哈希。
我是否正确地对密码进行了哈希处理,并且另外通过Base64编码密码哈希是否正确?
Base64编码不是唯一受支持的选项。您也可以执行十六进制编码。但是,您必须执行这两种操作之一,并且将JDBC Realm配置为在运行时执行相同的操作。如果没有编码参数,Glassfish会将与摘要相关的字节序列转换为为领域配置的charset
中的字符序列。
我怀疑问题与表达式input.getBytes("UTF-8")
中提到的UTF-8编码有关。值得验证digest
方法提供的结果的Base64编码是否确实与数据库中存储的密码哈希匹配。
另外,考虑到提供失败的原因是jdbcrealm.invaliduserreason
,我还怀疑以下条件之一可能成立:
没有为JDBC领域指定encoding参数。它最好是base64
或hex
之一(大小写无关紧要,取决于JDBC领域的源代码),否则您将最终遇到将摘要字节数组转换为字符数组的情况(我认为这有点不可靠,除非您可以保证用户提供的密码始终使用特定的编码)。
数据库中用户没有密码哈希。参见我以前对the SQL query executed的回答;您可能要自己运行查询。通过将名为derby.properties
的文件放在具有属性derby.language.logStatementText=true
的Derby数据库的位置,可以记录Derby发出的语句(如果您将其用作数据库)。关闭数据库后,将用应用程序服务器发出的所有查询填充derby.log文件。
Glassfish准备的SQL语句不正确。
无法建立与数据库的连接。