為了保證用戶的密碼在存儲到數據庫中時,不被惡意獲取,php提供了MD5加密方式來增強密碼的安全性。下面我們就來一起探究一下php MD5源碼的實現過程。
首先,我們需要了解一下密碼在加密過程中的轉化過程。例如,用戶的密碼為“123456”,則在加密之前,需要將該密碼轉化為對應的二進制形式。這可以通過php內置函數 pack() 來實現。代碼如下:
$password = pack("H*", md5("123456")); echo $password;
接下來,我們需要對轉換后的二進制進行處理。MD5算法采用了一種叫做“消息摘要”的方法,即通過將任意長度的“消息”(password)轉換成一定長度的“摘要”(hash值),來保證密碼的安全性。這個過程中,主要用到了4個函數:F、G、H、I。具體實現代碼如下:
// F函數 function F($x, $y, $z){ return ($x & $y) | (~$x & $z); } // G函數 function G($x, $y, $z){ return ($x & $z) | ($y & ~$z); } // H函數 function H($x, $y, $z){ return $x ^ $y ^ $z; } // I函數 function I($x, $y, $z){ return $y ^ ($x | ~$z); }
其中,符號“&”表示按位與運算,“|”表示按位或運算,“~”表示按位取反運算,“^”表示按位異或運算。通過調用這幾個函數,我們就可以對二進制進行多次處理,從而生成最終的MD5值。例如:
// 初始化參數 $a = 0x67452301; $b = 0xEFCDAB89; $c = 0x98BADCFE; $d = 0x10325476; // 填充 $msg = "123456"; $len = strlen($msg); $mod = $len % 64; $padding = $mod< 56 ? 56 - $mod : 120 - $mod; $msg .= chr(128); for($i = 0; $i< $padding - 1; $i++){ $msg .= chr(0); } $msg .= pack("Q*", 8 * $len); $chunk = str_split($msg, 64); // 對每個分塊進行處理 foreach($chunk as $block){ $j = array(); for($i = 0; $i< 16; $i++){ $j[$i] = unpack("V", substr($block, $i * 4, 4))[1]; } $AA = $a; $BB = $b; $CC = $c; $DD = $d; $a = $BB + (($a + F($b, $c, $d) + $j[0] + 0xD76AA478)<< 7 | ($a + F($b, $c, $d) + $j[0] + 0xD76AA478) >>25); $d = $a + (($d + F($a, $b, $c) + $j[1] + 0xE8C7B756)<< 12 | ($d + F($a, $b, $c) + $j[1] + 0xE8C7B756) >>20); $c = $d + (($c + F($d, $a, $b) + $j[2] + 0x242070DB)<< 17 | ($c + F($d, $a, $b) + $j[2] + 0x242070DB) >>15); $b = $c + (($b + F($c, $d, $a) + $j[3] + 0xC1BDCEEE)<< 22 | ($b + F($c, $d, $a) + $j[3] + 0xC1BDCEEE) >>10); $a = $b + (($a + F($b, $c, $d) + $j[4] + 0xF57C0FAF)<< 7 | ($a + F($b, $c, $d) + $j[4] + 0xF57C0FAF) >>25); ... } // 合并為一個32位整數 $ret = pack("V*", $a, $b, $c, $d); echo md5("123456"); // 輸出“e10adc3949ba59abbe56e057f20f883e”
好了,上面就是整個MD5加密的實現過程。相比于一些其他加密算法,MD5算法的實現過程可能稍微有些復雜。但是由于MD5算法在安全性上的保障效果非常顯著,所以該算法依然是php中最常用的加密方式之一。
上一篇ajax判斷內容是否一樣
下一篇css上邊框為點線