2011-07-28 202 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