2011-07-28 121 views
2

为了开发目的,我一直在以纯文本格式存储密码,但希望开始存储散列,但迄今尚未成功让GlassFish正确验证哈希密码,这是因为以下SecurityException:GlassFish SHA-256摘要式身份验证

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编码密码哈希?

谢谢!

回答

2

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境界不指定参数的编码;它应该最好是base64hex(案例无关紧要,以JDBC领域的源代码为准)中的一个,否则最终会出现在将摘要字节数组转换为字符数组的情况下(在我的意见是有点片状,除非你能保证用户提供的密码总是在一个特定的编码)。
  • 数据库中没有用户密码散列。看到我以前的回答the SQL query executed;你可能想自己运行查询。您可以记录Derby发布的语句(如果您将其用作数据库),请将名为derby.properties的文件放入Derby数据库的位置,其中包含属性derby.language.logStatementText=true。关闭数据库时,derby.log文件将填充应用程序服务器发出的所有查询。
  • Glassfish准备的SQL语句不正确。
  • 无法建立与数据库的连接。
+0

非常感谢!事实证明,我确实未能在JDBC领域指定编码参数,现在它正在正常工作! – Laurens

+0

@Laurens,啊,我在几个星期前与同样的野兽搏斗,所以你有没有经历过所有的麻烦。无论如何,该项目的来源将在几天内提供,因此您将能够看到正在运行的实施,而不是阅读我的答案。 –

+0

很高兴听到,期待! – Laurens