天天看點

java中驗證php crypt函數生成的密碼

        最近做的一個項目,想要使用公司的OA賬戶,但是OA系統是php語言開發的,首先要解決的就是如何在java中做密碼校驗,而OA系統使用的是php crypt()函數加密,剛開始想着通過相同的算法,生成密文,然後再與資料庫中存的密文做比較就可以了。但是,查了php crypt()函數的文檔:

java中驗證php crypt函數生成的密碼

         也就是說需要知道salt以及相應的加密方式才能生成密文,跟OA開發方聯系,懂的人不回信,回信的人又不懂,隻說使用crypt加密,salt都不知道,說問問别人再回複,頓時感覺沒指望啦,果不其然,一下班立馬聯系不上啦,關鍵時刻還得靠自己啊,谷哥度娘一起上,從網上下了一份老版本的源碼,雖然不是很全,但是還是有價值的,在修改密碼功能中發現了有用的東東:

$query = "SELECT PASSWORD,USEING_KEY from USER where USER_ID='".$LOGIN_USER_ID."'";
$cursor = exequery( $connection, $query );
if ( $ROW = mysql_fetch_array( $cursor ) )
{
				$PASSWORD = $ROW['PASSWORD'];
				$USEING_KEY = $ROW['USEING_KEY'];
				if ( crypt( $PASS0, $PASSWORD ) != $PASSWORD )
				{
								message( "錯誤", "輸入的原密碼錯誤!" );
								button_back( );
								exit( );
				}
}
$PASS1 = crypt( $PASS1 );
$CUR_TIME = date( "Y-m-d H:i:s", time( ) );
$query = "update USER SET PASSWORD='".$PASS1."',LAST_PASS_TIME='{$CUR_TIME}' where USER_ID='{$LOGIN_USER_ID}'";
exequery( $connection, $query );
           

         從上面來看,密碼的生成是直接調用crypt()函數的,沒有加salt,根據文檔,是按照響應的規則自動随機生成的,并且每次生成的都不一樣,也就是說,根據隻有明文是不能直接得到密文的,此路不通,隻能另辟蹊徑。再看上面輸出message()的if語句條件 crypt( $PASS0, $PASSWORD ) != $PASSWORD,這個也就是判斷密碼是否正确的條件,裡面的$PASS0是密碼的明文,$PASSWORD是資料庫裡面存的密文,按照這個邏輯,使用php代碼将已知的密碼明文以及密碼密文做個驗證,這裡有個線上運作php以及其他語言代碼的網站,還不錯:http://codepad.org,經驗證,所有測試的密碼明文和密文都是比對的,也就是說在目前版本的OA系統中,這塊兒的邏輯還沒有發生變化。

        現在的問題就是找到該crypt方法的java語言實作,還是谷哥給力,在http://stackoverflow.com/questions/3292160/equivalent-of-phps-crypt-function-in-java中有人提到了apache的commons-codes裡面的兩個類UnixCript 和Md5Crypt,經過檢視java doc以及測試,最終證明Md5Crypt中的md5Crypt方法可以實作上述php代碼中crypt的功能。Over!

        雖然問題得到了解決,但是還有疑問有待進一步研究:為什麼crypt( $PASS0, $PASSWORD ) == $PASSWORD 就可以說明密碼正确了?(這個可能需要詳細了解其加密算法)