使用MD5變換算法來(lái)防止窮舉破譯密碼(一)

MD5是在Web應(yīng)用程序中最常用的密碼加密算法。由于MD5是不可逆的,因而經(jīng)過(guò)MD5計(jì)算得到后的密文,不能通過(guò)逆向算法得到原文。

回顧在Web應(yīng)用程序中使用MD5加密文本密碼的初衷,就是為了防止數(shù)據(jù)庫(kù)中保存的密碼不幸泄露后被直接獲得。但攻擊者不但擁有數(shù)據(jù)量巨大的密碼字典,而且建立了很多MD5原文/密文對(duì)照數(shù)據(jù)庫(kù),能快速地找到常用密碼的MD5密文,是破譯MD5密文的高效途徑。然而,MD5密文數(shù)據(jù)庫(kù)所使用的是最常規(guī)的MD5加密算法:原文-->MD5-->密文。因此,我們可以使用變換的MD5算法,使現(xiàn)成的MD5密文數(shù)據(jù)庫(kù)無(wú)所作為。

下面演示一些變換算法的例子,當(dāng)然,在其它的Web開發(fā)語(yǔ)言中,也大同小異,完全能得到相同的結(jié)果。

變換一:循環(huán)MD5

最容易理解的變換就是對(duì)一個(gè)密碼進(jìn)行多次的MD5運(yùn)算。自定義一個(gè)函數(shù),它接受$data和$times兩個(gè)形參,第一個(gè)是要加密的密碼,第二個(gè)是重復(fù)加密的次數(shù)。實(shí)現(xiàn)這種變換有兩種算法:

//迭代算法

function md5_1_1($data, $times = 32)

{

//循環(huán)使用MD5

for ($i = 0; $i < $times; $i++) {   $data = md5($data);   }   return $data;   }   //遞歸算法   function md5_1_2($data, $times = 32)   {   if ($times > 0) {

$data = md5($data);

$times--;

return md5_1_2($data, $times); //實(shí)現(xiàn)遞歸

} else {

return $data;

}

}

?>

變換二:密文分割MD5

盡管用戶的密碼是不確定的字符串,但是只要經(jīng)過(guò)一次MD5運(yùn)算后,就會(huì)得到一個(gè)由32個(gè)字符組成的字符串,這時(shí)可以再針對(duì)這個(gè)定長(zhǎng)字符串變換。有點(diǎn)BT的算法是,把這段密文分割成若干段,對(duì)每段都進(jìn)行一次MD5運(yùn)算,然后把這堆密文連成一個(gè)超長(zhǎng)的字符串,最后再進(jìn)行一次MD5運(yùn)算,得到仍然是長(zhǎng)度為32位的密文。

//把密文分割成兩段,每段16個(gè)字符

function md5_2_1($data)

{

//先把密碼加密成長(zhǎng)度為32字符的密文

$data = md5($data);

//把密碼分割成兩段

$left = substr($data, 0, 16);

$right = substr($data, 16, 16);

//分別加密后再合并

$data = md5($left).md5($right);

//最后把長(zhǎng)字串再加密一次,成為32字符密文

return md5($data);

}

//把密文分割成32段,每段1個(gè)字符

function md5_2_2($data)

{

$data = md5($data);

//循環(huán)地截取密文中的每個(gè)字符并進(jìn)行加密、連接

for ($i = 0; $i < 32; $i++) {   $data .= md5($data{$i});   }   //這時(shí)$data長(zhǎng)度為1024個(gè)字符,再進(jìn)行一次MD5運(yùn)算   return md5($data);   }   ?>

當(dāng)然,這種密文分割的具體算法是數(shù)之不盡的,比如可以把原密文分割成16段每段兩字符、8段每段4字符,或者每一段的字符數(shù)不相等……