MD5 到底是什麼
很多人把 MD5 叫做"MD5加密",這個說法從一開始就是錯的。
MD5 是一種哈希函數(Hash Function),不是加密算法。兩者有本質區別:
- 加密:可逆操作,有密鑰,能解密還原原始數據
- 哈希:不可逆操作,無密鑰,理論上無法從結果推回原始數據
MD5 的作用是把任意長度的輸入,變成一個固定 128 位(32個十六進制字符)的輸出,稱爲"摘要"或"指紋"。
MD5("hello") = 5d41402abc4b2a76b9719d911017c592
MD5("hello!") = 9b56e4f280d7b27a6c8d0c11d5a8cb7d
MD5("一篇很長的文章...") = d41d8cd98f00b204e9800998ecf8427e
三個特性:
- 單向性:無法從哈希值逆推原始內容
- 固定長度:無論輸入多長,輸出始終 32 位
- 雪崩效應:輸入改動一個字節,輸出完全不同
MD5 能被"破解"嗎
嚴格來說,MD5 無法被"解密"——因爲它不是加密。但它可以被暴力破解或查表攻擊。
暴力破解
最簡單的思路:把常見密碼逐個計算 MD5,和目標哈希值對比。
計算 MD5("123456") = e10adc3949ba59abbe56e057f20f883e ← 匹配!
現代 GPU 每秒可以計算數十億次 MD5,123456、password、qwerty 這類常見密碼在不到一秒內就能找到。
彩虹表攻擊
暴力破解需要實時計算,而彩虹表是預先計算好的海量明文-哈希值對照表,空間換時間。
攻擊者拿到一個 MD5 哈希值,直接在表裏查找,瞬間得到原始密碼。網上有公開的 MD5 彩虹表,覆蓋數百億條常見密碼和短字符串組合。
實際上,很多"MD5在線解密"網站的原理就是這個——它們維護了一張巨大的哈希-明文數據庫,輸入哈希值查表返回結果,不是真正的"解密"。
MD5 碰撞
2004年,研究人員找到了 MD5 的碰撞攻擊方法:可以構造出兩個不同的輸入,產生完全相同的 MD5 值。這從根本上動搖了 MD5 作爲完整性校驗工具的可信度。
文件A 和 文件B 內容完全不同,但 MD5 值完全相同
這意味着攻擊者可以僞造一個與合法文件 MD5 值相同的惡意文件,繞過完整性校驗。
爲什麼還有人用 MD5 存密碼
歷史原因。MD5 在 1991 年發佈時被認爲足夠安全,大量早期系統將其用於密碼存儲。隨着計算能力的提升和攻擊方法的演進,MD5 的安全性早已不夠,但遺留系統的遷移成本很高,導致至今仍有系統在用。
2012年 LinkedIn 數據泄露事件中,約 650 萬條密碼以未加鹽的 SHA-1 哈希存儲;更早的數據泄露中,大量網站使用的正是裸 MD5。泄露後,攻擊者在數小時內就破解了絕大多數密碼。
正確的密碼存儲方案
加鹽(Salt)
給每個密碼在哈希前拼接一段隨機字符串(鹽值),使得相同的密碼產生不同的哈希結果,從而讓彩虹表完全失效。
salt = "xK92mP" // 每個用戶隨機生成,存入數據庫
hash = MD5(password + salt)
但即便加鹽,MD5 本身計算太快,GPU 暴力破解仍然可行。
bcrypt:專爲密碼存儲設計
bcrypt 是目前最主流的密碼哈希方案,有幾個關鍵特性:
1. 內置鹽值:每次哈希自動生成隨機鹽,無需手動處理。
2. 計算成本可調:通過 cost factor 參數控制哈希運算的計算量,隨硬件提升可以相應調高,保持破解難度。
3. 故意很慢:正常用戶登錄只需驗證一次,慢一點無所謂;但攻擊者需要暴力嘗試數十億次,慢就是致命的。
import bcrypt
# 註冊:生成哈希
password = b"user_password"
hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))
# 存入數據庫的是 hashed,不是原始密碼
# 登錄:驗證
bcrypt.checkpw(password, hashed) # 返回 True/False
Argon2:更現代的選擇
Argon2 是 2015 年密碼哈希競賽的冠軍算法,在 bcrypt 基礎上增加了內存佔用控制,進一步提升了對 GPU 和 ASIC 暴力破解的抵抗力。新項目首選 Argon2id。
from argon2 import PasswordHasher
ph = PasswordHasher(time_cost=2, memory_cost=65536, parallelism=2)
hashed = ph.hash("user_password")
ph.verify(hashed, "user_password") # 驗證
scrypt
與 Argon2 類似,也是內存密集型哈希,Node.js 標準庫內置支持,適合 JavaScript 後端。
MD5 現在還能用在哪裏
MD5 不適合安全場景,但在以下非安全場景中仍然合理:
文件完整性校驗(非安全環境)
下載文件後對比 MD5 值,確認文件未被損壞(注意:不能防止有意篡改,只能檢測傳輸錯誤)。
# Linux/macOS
md5sum filename.zip
# macOS
md5 filename.zip
生成唯一標識符
對內容取 MD5 作爲緩存 key、去重 ID 等,不涉及安全的場景。
數據庫內容去重
對大文本字段取 MD5 建索引,快速判斷是否重複。
非安全場景的數據指紋
日誌系統、數據管道里對數據做快速摘要,用於追蹤和對比。
一句話總結
| 場景 | 推薦方案 |
|---|---|
| 用戶密碼存儲 | bcrypt 或 Argon2id |
| 文件完整性校驗(安全) | SHA-256 |
| 文件完整性校驗(非安全) | MD5 可用 |
| 數字簽名 | RSA + SHA-256 |
| 緩存 Key / 去重 ID | MD5 可用 |
密碼存儲永遠不要用 MD5,不管加不加鹽。
在線工具
如果你需要計算一段文本的 MD5 值用於數據校驗或測試,可以使用 toolshu.com 的 MD5 在線加密工具,支持 16 位和 32 位輸出,大小寫均可,在瀏覽器本地運算不上傳數據。



加載中...