256摘要认证
为了开发目的,我一直以纯文本格式存储密码,但是希望开始存储哈希值,但由于以下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编码密码哈希?
谢谢!
GlassFish是否期望String(VARCHAR)或byte [](BLOB)作为数据库中的密码字段?
它期望一个映射到JDBC中的Java Type 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
,我也会怀疑下列情况之一可能是正确的:
base64
或hex
(这种情况并不重要,以JDBC领域的源代码为准),否则最终会出现在将摘要字节数组转换为字符数组的情况下(在我的意见是有点片状,除非你能保证用户提供的密码总是在一个特定的编码)。 derby.properties
的文件放置在Derby数据库的位置,其中包含属性derby.language.logStatementText=true
。 关闭数据库时,derby.log文件将填充应用程序服务器发出的所有查询。