跳到主要內容

← 返回部落格

MD5 安全嗎?什麼還能用、什麼不能用

簡短答案:只要牽涉到攻擊者,MD5 就不安全。它很快、拿來做非安全性檢查仍方便,但把它當安全工具用是實實在在的風險。以下說明細節。

這個值你可以拿任何工具核對。 我們把 hello 這一個字丟進雜湊產生器,MD5 得到 5d41402abc4b2a76b9719d911017c592。在任何機器上跑 echo -n hello | md5sum 都會得到同樣的 32 個字元 —— 而這正是問題所在。MD5 快、確定、到處都有實作,所以手上有預算表的攻擊者查一下就找到了。同一個字的 SHA-256 是 2cf24dba…938b9824,它更安全不是因為比較長,而是因為目前沒有可實用的碰撞攻擊。對密碼來說兩者都不適合:你要的是刻意很慢的函式,例如 bcrypt 或 Argon2。

為什麼 MD5 被視為已攻破

MD5 有碰撞弱點——兩個不同輸入產生相同雜湊——而且能低成本製造。這破壞了任何「要用雜湊證明某件攻擊者無法偽造之事」的用途。它又極快,讓暴力破解變得容易。

MD5 還能安全做什麼

  • 非對抗性的校驗碼——偵測檔案意外損毀,或當快取/去重的鍵,沒有攻擊者想騙你的情境。
  • 內部、非安全目的的快速指紋

MD5 不該用來做什麼

  • 密碼——絕對不行。而且光用 SHA-256 也不行。密碼需要慢速、加鹽的演算法,如 bcrypt、scrypt 或 Argon2。(更好的做法:別自己造,用框架內建的驗證。)
  • 數位簽章、憑證、防竄改完整性——請用 SHA-256(SHA-2)或 SHA-3。

完整比較見 MD5 vs SHA

自己試試

結論:MD5 用於偵測意外錯誤的校驗、SHA-256 用於完整性、密碼則用專門的雜湊(bcrypt/Argon2)。

下表每一列都是我們自己的雜湊產生器跑出來的,而且每一列你都可以在自己的機器上用 echo -n hello | md5sum 核對。這才是重點 —— 這些值不需要你信任我們。 標示的是結尾的一個空白。

輸入MD5
hello5d41402abc4b2a76b9719d911017c592
Hello8b1a9953c4611296a827abf8c47804d7
hell073b43f17232b391b9123adf40c1b65dd
hello␠f814893777bcc2295fff05f00e508da6
password5f4dcc3b5aa765d61d8327deb882cf99

MD5 是怎麼倒下的

MD5 不是一夕崩壞,裂縫在二十年間逐漸擴大:

  • 1991 年——MD5 發表,產生 128 位元(32 個十六進位字元)的摘要。
  • 1996 年——其壓縮函式首度被發現嚴重弱點。
  • 2004–2005 年——研究者能在數小時、進而數分鐘內做出完整碰撞。
  • 2008 年——有人靠 MD5 碰撞偽造出可運作的憑證頒發機構(CA)。
  • 2012 年——Flame 惡意程式利用 MD5「選定前綴碰撞」偽造出微軟的程式碼簽章憑證。

規律本身就是教訓:一旦碰撞變便宜,真實世界的攻擊就會跟上。SHA-1 也走了同一條路——首個公開碰撞在 2017 年出現——所以新專案應改用 SHA-256 或更強的演算法。

怎麼選對演算法

演算法輸出長度現況適用
MD5128 位元碰撞已被便宜攻破偵測意外損毀的校驗、快取鍵
SHA-1160 位元碰撞已被攻破(2017)僅限舊系統——新專案避免
SHA-256(SHA-2)256 位元安全完整性、簽章、憑證
SHA-3224–512 位元安全SHA-2 的現代替代
bcrypt / scrypt / Argon2可調安全,刻意設計得慢密碼

挑替代品就是在挑摘要寬度,而一個輸入就能讓寬度變具體。hello 在 SHA-256 下是

2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

在 SHA-512 下是

9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043

那是 64 對 128 個十六進位字元 —— 256 對 512 位元 —— 對同一個五個字母的輸入。兩個在瀏覽器裡的計算速度差異你都不會注意到,所以實務規則很簡單:用 SHA-256,除非某個你必須互通的東西要求 SHA-512。不該做的是「挑一個更寬的摘要,然後繼續拿它當密碼雜湊」——寬度不等於慢,而密碼儲存需要的是慢。

實際驗證校驗碼

當下載頁列出雜湊值,你可以自己算一份來比對:

# 只能確認檔案在傳輸中沒有損壞
md5sum ubuntu.iso

# 只要來源可能被竄改,就該用這個
sha256sum ubuntu.iso

MD5 相符只代表位元組完整送達;它不能證明沒人把檔案掉包,因為相符的 MD5 是可以偽造的。要那種保證,請用 SHA-256 再加上簽章。

看第四列。hello 後面多一個空白,雜湊變成 f814893777bcc2295fff05f00e508da6,和 5d41402abc4b2a76b9719d911017c592 完全沒有任何共同之處。大部分「校驗碼對不上」的回報其實就是這個,根本不是檔案損壞:編輯器加了換行,或者複製貼上帶進了空白。而最後一列用一個值就把「MD5 不能拿來存密碼」講完了 —— 5f4dcc3b5aa765d61d8327deb882cf99password 的 MD5,它出現在所有公開過的彩虹表裡。把那串丟進搜尋引擎立刻就看到明文,完全不需要碰撞攻擊。

常見問答

MD5 是加密嗎?

不是。MD5 是單向雜湊——沒有金鑰,也沒有東西可以「解密」。所謂的「MD5 解密」網站,其實只是預先算好的雜湊對照資料庫。

加鹽的 MD5 拿來存密碼安全嗎?

不安全。加鹽能讓相同密碼不再共用同一雜湊、擋掉彩虹表,但 MD5 太快,握有你資料庫的攻擊者每秒仍可嘗試數十億次。請改用 bcrypt 或 Argon2 這類慢速雜湊——見強密碼指南

我要下載的檔案只提供 MD5 校驗碼,那沒用嗎?

並非沒用。它能可靠地抓出下載損毀。它只是無法防止惡意掉包;當來源不可信時,優先選 SHA-256 加簽章。