1. 程式人生 > >存入資料庫後,涉及到密碼問題

存入資料庫後,涉及到密碼問題

                          存入資料庫後,涉及到密碼問題

 

轉載:https://blog.csdn.net/gredn/article/details/27196379?utm_source=blogxgwz9

當你通過telnet新增新使用者時,比如adduser holen 123456,你可以檢視資料庫中的記錄,第一個欄位是holen,第二欄位是密碼,但密碼並非123456,而一串“亂碼”(zhwQUMTwdMqWfm/h0biB51Gf)??這是加密碼後的密碼內容,再看後面的欄位是“SHA”,顯然用的是SHA加密方式。

通過telnet方式新增新使用者,使用者密碼將自動加密,然後插入資料庫中。但通過telnet方式進行使用者管理有著諸多不便,儘管你可以藉助James的一個RMI工具包,提高效率,但仍然沒有本質改變,當需要用作商業用途時,你更不能要求你的客戶熟記那一堆命令符。

一般我們可以做一個Web前端,通過網頁形式,新增修改使用者,介面友好,傻瓜化使用,如263或163一樣。若這樣做,我們就需要直接操作資料庫,新增使用者記錄或修改刪除使用者記錄了。但別忘了,James預設對使用者密碼是加密的,既然我們要直接操作資料庫,那麼我們只有兩個選擇:要麼我們研究其密碼機制,新增記錄時,我們對新增使用者的密碼進行同樣加密,要麼我們去掉James的加密機制,使其明碼儲存。

幸好,這兩種選擇都是可行的。我們從Apache網站下載James的原始碼包,下載後的檔案為james-2.1-src.zip,接近8M,通過分析原始碼,我們發現,與使用者密碼相關的檔案是DefaultUser.java,部分原始碼如下:
 

package org.apache.james.userrepository;
……
/**
      *   Method to verify passwords. 
      *
      * @param pass the String that is claimed to be the password for this user
      * @return true if the hash of pass with the current algorithm matches
      * the stored hash.
      */
     public boolean verifyPassword(String pass) {
         try {
             String hashGuess = DigestUtil.digestString(pass, algorithm);
             return hashedPassword.equals(hashGuess);
         } catch (NoSuchAlgorithmException nsae) {
         throw new RuntimeException("Security error: " + nsae);
     }
     }

     /**
      * Sets new password from String. No checks made on guessability of
      * password.
      *
      * @param newPass the String that is the new password.
      * @return true if newPass successfuly hashed
      */
     public boolean setPassword(String newPass) {
         try {
             hashedPassword = DigestUtil.digestString(newPass, algorithm);
             return true;
         } catch (NoSuchAlgorithmException nsae) {
             throw new RuntimeException("Security error: " + nsae);
         }
}
…… 

第一個方法verifyPassword()是用來做密碼認證,傳入的引數是明文密碼,通過DigestUtil.digestString()方法,轉換成密文密碼,然後與資料庫中密碼作比較,返回比較結果。請注意這裡的DigestUtil.digestString()方法,在後面還在提到。

第二個方法setPassword()是用於密碼轉換的,把明文轉成密文,用的同樣是DigestUtil.digestString()方法。

談到這裡,相信你應該知道怎麼在自己的程式中進行密碼轉換和密碼認證了吧!其實並不是要你自己去寫一個SHA的加密演算法,既然James已經提供了此功能,你呼叫便是了。

還有一種情況,開發者需要在資料庫中必須用明文儲存密碼,這樣就不必在自己寫的程式中進行密碼轉換了,而且當多個應用系統採用統一使用者模型時,最好只有一個使用者例項。要實現這個需求,就只能修改James原始碼了,把verifyPassword()方法和setPassword()改成:
 

public boolean verifyPassword(String pass) {       
             return hashedPassword.equals(pass);       
}   
public boolean setPassword(String newPass) {      
             hashedPassword = newPass;
             return true;       
} 

其實就是把轉換過程去掉,儲存和認證就都採用明文進行了。

你要是覺得SHA方式不妥,也可以掛接別的加密方式,同樣是修改這兩個方法。

注意,當你修改了James的原始碼後,你需要用Ant重新build James專案,build後將在james-2.1-srcdistjames-2.1apps下面找到新生成的james.sar檔案。把該檔案覆蓋James原來james.sar,並刪除與james.sar同級的james目錄,重啟動james即可。建議保留原來的config.xml,免得又配一次。

通過以上探討,我們明白瞭如何通過Web方式進行使用者註冊和使用者登記等。需要說明一點是,James自動生成的users表中只有7個欄位,而且都是系統需要使用的。一般註冊時需要輸入的資訊項比較多,這時建議開發者自己再建一個新表USERINFO,用username把兩個表關聯起來,不建議修改users表的內容(如果想試試,請參考file://conf/sqlResources.xml)。