PHP MD5加密解密原理詳解

一、什麼是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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
DTTI的頭像DTTI
上一篇 2024-10-14 18:45
下一篇 2024-10-14 18:45

相關推薦

  • PHP和Python哪個好找工作?

    PHP和Python都是非常流行的編程語言,它們被廣泛應用於不同領域的開發中。但是,在考慮擇業方向的時候,很多人都會有一個問題:PHP和Python哪個好找工作?這篇文章將從多個方…

    編程 2025-04-29
  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • Harris角點檢測算法原理與實現

    本文將從多個方面對Harris角點檢測算法進行詳細的闡述,包括算法原理、實現步驟、代碼實現等。 一、Harris角點檢測算法原理 Harris角點檢測算法是一種經典的計算機視覺算法…

    編程 2025-04-29
  • 瘦臉算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉算法 Python 實現的原理和方法,包括該算法的意義、流程、代碼實現、優化等內容。 一、算法意義 隨着科技的發展,瘦臉算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29
  • PHP怎麼接幣

    想要在自己的網站或應用中接受比特幣等加密貨幣的支付,就需要對該加密貨幣擁有一定的了解,並使用對應的API進行開發。本文將從多個方面詳細闡述如何使用PHP接受加密貨幣的支付。 一、環…

    編程 2025-04-29
  • 神經網絡BP算法原理

    本文將從多個方面對神經網絡BP算法原理進行詳細闡述,並給出完整的代碼示例。 一、BP算法簡介 BP算法是一種常用的神經網絡訓練算法,其全稱為反向傳播算法。BP算法的基本思想是通過正…

    編程 2025-04-29
  • 使用PHP foreach遍歷有相同屬性的值

    本篇文章將介紹如何使用PHP foreach遍歷具有相同屬性的值,並給出相應的代碼示例。 一、基礎概念 在講解如何使用PHP foreach遍歷有相同屬性的值之前,我們需要先了解幾…

    編程 2025-04-28
  • GloVe詞向量:從原理到應用

    本文將從多個方面對GloVe詞向量進行詳細的闡述,包括其原理、優缺點、應用以及代碼實現。如果你對詞向量感興趣,那麼這篇文章將會是一次很好的學習體驗。 一、原理 GloVe(Glob…

    編程 2025-04-27
  • PHP獲取301跳轉後的地址

    本文將為大家介紹如何使用PHP獲取301跳轉後的地址。301重定向是什麼呢?當我們訪問一個網頁A,但是它已經被遷移到了另一個地址B,此時若服務器端做了301重定向,那麼你的瀏覽器在…

    編程 2025-04-27
  • 編譯原理語法分析思維導圖

    本文將從以下幾個方面詳細闡述編譯原理語法分析思維導圖: 一、語法分析介紹 1.1 語法分析的定義 語法分析是編譯器中將輸入的字符流轉換成抽象語法樹的一個過程。該過程的目的是確保輸入…

    編程 2025-04-27

發表回復

登錄後才能評論