一、什麼是MD5加密?
MD5加密是一種單向加密算法,將任意長度的數據加密成固定長度的密文。主要被用於密碼加密,數字簽名等領域。
MD5加密特點:
1、加密結果是固定長度的128bit字符串,不管加密前數據的長度多長,密文長度始終為128bit。
2、同樣的數據進行MD5加密後,生成的密文總是相同的。
3、密文經MD5加密後無法通過任何手段還原為明文。
二、MD5加密的實現原理
MD5加密通過對明文進行多次處理,生成固定長度的密文。處理過程主要包括以下幾步:
1、填充
將明文進行長度擴展,使其長度滿足448mod512,並在其末尾添加一個64bit的數據,用於保存明文本身的長度。
//填充函數
function padding($str){
$len = strlen($str); //得到字符串長度
$pad_len = 448 - $len % 512; //計算需要填充的長度
if($pad_len <= 64) //如果需要填充的長度介於1-64之間,則需要加一個分組
$pad_len += 512;
$pad_char = chr($pad_len/8); //計算需要填充的字符
$padding_str = "";
for($i=0; $i<$pad_len/8; $i++)
$padding_str .= $pad_char;
$padding_str .= $str.pack("Q*", $len*8); //連接原始數據長度
return $padding_str;
}
2、初始化
對填充後的明文進行初始化,生成4個32bit的緩存區,對應a、b、c、d。根據RFC1321規格定義的初始值,將a、b、c、d設置成如下值:
a = 0x67452301
b = 0xEFCDAB89
c= 0x98BADCFE
d=0x10325476
//初始化MD5狀態變量
$A = 0x67452301;
$B = 0xEFCDAB89;
$C = 0x98BADCFE;
$D = 0x10325476;
3、四輪迭代
將初始化後的緩存區與每個512位的分組進行四輪迭代計算,每輪迭代對緩存區進行ABCD四個變量的置換。
//四輪迭代
function md5_loop($f, $m, $s, $i){
global $A, $B, $C, $D;
if($f == 'F')
$res = ($B & $C) | (~$B & $D);
else if($f == 'G')
$res = ($B & $D) | ($C & ~$D);
else if($f == 'H')
$res = ($B ^ $C ^ $D);
else if($f == 'I')
$res = ($C ^ ($B | ~$D));
$temp = $B + shiftleft(($A + $res + $m + $s[$i]), $i*5%32);
$A = $D;
$D = $C;
$C = $B;
$B = $temp;
}
//用於循環左移
function shiftleft($num, $bits){
$num = $num & 0xffffffff; //強制截斷為32位
$num_str = decbin($num); //轉換為二進制字符串
$num_str = str_pad($num_str, 32, 0, STR_PAD_LEFT); //補充0,使其長度變成32位
$num_str = substr($num_str, $bits).substr($num_str, 0, $bits); //將字符串分為兩部分,分別進行循環左移
return bindec($num_str); //將處理結果返回為十進制數
}
4、生成密文
經過四輪迭代之後,將四個緩存區連接起來,組成128bit長度的MD5摘要,即為密文。
//生成MD5摘要
function md5($str){
$padding_str = padding($str);
$chunk = strlen($padding_str) / 64; //分段
for($i=0; $i<$chunk; $i++){
$str_chunk = substr($padding_str, $i*64, 64); //得到每一段字符串
$word = array();
for($j=0; $j<16; $j++){
$word[] = unpack("V", substr($str_chunk, $j*4, 4))[1]; //將字符串分為16組,每組4個字節,然後將每組轉換成unsigned int數值
}
//四輪迭代
$s = array(7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21);
$K = array(0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391);
for($j=0; $j<64; $j++){
if($j<16){
md5_loop('F', $word[$j], $s, $j);
}
else if($j<32){
md5_loop('G', $word[(5*$j+1)%16], $s, $j);
}
else if($j<48){
md5_loop('H', $word[(3*$j+5)%16], $s, $j);
}
else{
md5_loop('I', $word[(7*$j)%16], $s, $j);
}
}
}
$md5_str = pack("V4", $A, $B, $C, $D); //將4個緩存區合併成字符串
return bin2hex($md5_str); //將字符串轉換成16進制數值
}
三、MD5解密
MD5加密是一種單向加密算法,無法通過密文還原明文。但是可以通過窮舉法,對所有可能的明文進行加密,找到和密文一致的密文,即為原來的明文。
//MD5解密
function md5_decrypt($str, $target_md5_str){
$padding_str = padding($str);
$chunk = strlen($padding_str) / 64;
for($i=0; $i<$chunk; $i++){
$str_chunk = substr($padding_str, $i*64, 64); //得到每一段字符串
$word = array();
for($j=0; $j<16; $j++){
$word[] = unpack("V", substr($str_chunk, $j*4, 4))[1]; //將字符串分為16組,每組4個字節,然後將每組轉換成unsigned int數值
}
//四輪迭代
$s = array(7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21);
$K = array(0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd原創文章,作者:DTTI,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/143090.html