在Web 開發中,用戶密碼的安全存儲是一項基礎且至關重要的任務。然而,儘管安全知識不斷普及,仍有許多開發者在初學PHP 或構建簡單系統時,習慣性地使用md5()函數對用戶密碼進行加密存儲。今天我們就來聊聊,用md5存密碼到底安不安全,以及這一做法背後存在哪些常見誤區。
md5()是PHP 內置的一個哈希函數,它可以將任意長度的字符串轉換成一個32 字符長度的十六進製字符串。例如:
<span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">md5</span></span><span>(</span><span><span class="hljs-string">'password123'</span></span><span>); </span><span><span class="hljs-comment">// 輸出:482c811da5d5b4bc6d497ffa98491e38</span></span><span>
</span></span>
這是一個不可逆的散列過程(理論上)。早期許多開發者將其用於對用戶密碼進行“加密”存儲,認為這樣可以保護用戶的隱私。
答案是:不安全,早已被淘汰。
主要原因有以下幾點:
md5()本意是用於校驗數據完整性的哈希函數,它的計算速度極快。然而,正因為速度快,使得它非常容易被用於暴力破解攻擊(brute force attack)或彩虹表攻擊(rainbow table attack)。
攻擊者可以在極短的時間內嘗試大量組合來猜測出原始密碼,特別是對於常見或弱密碼幾乎毫無抵抗能力。
md5()是確定性函數——相同輸入永遠產生相同輸出。這就導致如果兩個用戶的密碼相同,其生成的哈希值也相同,攻擊者只需破解一次,即可適用於多個賬戶。
而沒有加鹽的哈希存儲方式,是非常容易被彩虹表擊穿的。
互聯網上存在大量md5哈希與明文密碼的映射數據庫,例如:你只需要將md5('123456')得到的哈希值粘貼進搜索引擎,往往立刻能查到原始密碼。
PHP 從5.5 版本起提供了password_hash()和password_verify()這兩個函數,是目前推薦用於密碼加密和驗證的方式。
示例代碼如下:
<span><span><span class="hljs-comment">// 生成密碼哈希</span></span><span>
</span><span><span class="hljs-variable">$hash</span></span><span> = </span><span><span class="hljs-title function_ invoke__">password_hash</span></span><span>(</span><span><span class="hljs-string">'password123'</span></span><span>, PASSWORD_DEFAULT);
</span><span><span class="hljs-comment">// 驗證密碼</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">password_verify</span></span><span>(</span><span><span class="hljs-string">'password123'</span></span><span>, </span><span><span class="hljs-variable">$hash</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">'密碼正確'</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">'密碼錯誤'</span></span><span>;
}
</span></span>
password_hash()默認使用bcrypt算法,並自動生成隨機鹽值,內置抗擊暴力破解和彩虹表攻擊的機制。
自動加鹽
可配置計算強度(成本因子)
可擴展(支持不同的算法,如Argon2)
官方維護,符合現代密碼存儲標準
使用md5()存儲密碼是過時且危險的做法,雖然在早期項目中較為常見,但在今天已經不再安全。隨著網絡攻擊手段的不斷升級,開發者應摒棄陳舊的安全觀念,使用更現代、更安全的方式來處理用戶密碼。
記住:安全不是靠“加密”,而是靠設計。
擁抱password_hash() ,拒絕md5() ,是對用戶安全最基本的尊重。