軟體加密原理:為什麼雜湊函數
「雜湊」與「加密」最根本的差異,在於是否可逆。加密是一種雙向的過程:明文經過金鑰與演算法變成密文,而持有正確金鑰的人可以將密文解密回明文。雜湊則是單向的:資料經過運算變成摘要後,就再也回不去了。
這個差異決定了兩者在實務上的分工。當你需要「保護資料內容、但之後還要還原」時,例如傳輸信用卡號或儲存醫療紀錄,你會使用加密。當你只需要「驗證資料是否相同、是否被竄改」,而不需要還原原始內容時,例如儲存密碼、驗證檔案完整性,你就會使用雜湊。
一個常見的嚴重錯誤,就是開發者把密碼用對稱式加密儲存起來,以為這樣比較安全。問題在於,只要伺服器持有解密金鑰,一旦資料庫外洩,攻擊者就能還原所有密碼。相反地,若採用正確的密碼雜湊設計,即使資料庫被整碗端走,攻擊者也難以在合理時間內還原出明文密碼。這正是為什麼現代系統幾乎一律採用雜湊而非加密來處理密碼。
二、雜湊函數在軟體加密中的關鍵角色
理解了基本原理後,我們來看看雜湊函數究竟在哪些實際場景中發揮作用。可以說,現代軟體的安全架構中,雜湊函數無所不在,只是多數時候使用者並不會察覺。
密碼儲存:為什麼不該明文保存密碼
這是雜湊函數最廣為人知的應用,卻也是實作上最容易出錯的地方。理想情況下,伺服器不應該儲存使用者的明文密碼,而是儲存密碼經過雜湊運算後的摘要。當使用者登入時,系統將輸入的密碼重新雜湊一次,再與資料庫中的摘要比對,若一致即代表密碼正確。
這樣的設計帶來一個重要好處:即使資料庫遭竊,攻擊者拿到的也只是雜湊值,無法直接得知密碼。然而,單純的雜湊並不足夠。攻擊者可以預先計算常見密碼的雜湊值,建立所謂的彩虹表(Rainbow Table),或是使用暴力破解與字典攻擊,快速反查出弱密碼。為了對抗這類攻擊,現代密碼儲存必須結合加鹽(Salting)與密鑰拉伸(Key Stretching)兩種技術。
加鹽是指在雜湊前,為每位使用者產生一段隨機且唯一的字串(鹽值),與密碼串接後再進行雜湊。如此一來,即使兩位使用者使用相同的密碼,其雜湊值也會完全不同,彩虹表便失去效用。密鑰拉伸則是刻意讓雜湊計算變得「慢」,例如透過反覆迭代數千次,或用專門設計的演算法如 bcrypt、scrypt、Argon2,大幅增加攻擊者逐一測試密碼的成本。這點我們會在後面的實務章節進一步討論。
數位簽章與訊息完整性驗證
在網路傳輸中,我們經常需要確認「收到的資料就是對方送出的資料,且中途沒有被竄改」。雜湊函數在此扮演了訊息指紋的角色。傳送方可以計算檔案的雜湊值,並透過獨立管道提供給接收方;接收方下載檔案後自行計算雜湊值,若兩者一致,即可高度確信檔案內容完整無誤。
這種機制被廣泛應用於軟體下載頁面、作業系統更新、韌體驗證等場景。你在下載 Linux 映像檔時看到的 SHA-256 校驗碼,就是這個原理的實際應用。更進一步,當雜湊函數與非對稱式加密結合,就形成了數位簽章(Digital Signature):簽署者先對訊息計算雜湊值,再用私鑰對該雜湊值加密,驗證者則用公鑰解密並比對雜湊值。由於雜湊值遠短於原始訊息,這種設計大幅提升了簽章效率,同時確保訊息的完整性與不可否認性。
區塊鏈與雜湊鏈結
近十年最受矚目的雜湊應用,莫過於區塊鏈。區塊鏈之所以稱為「鏈」,正是因為每個區塊都包含了前一個區塊的雜湊值,形成一條不可篡改的鏈結。任何人若想修改歷史上的某個區塊,就必須連帶修改其後所有區塊的雜湊值,且必須重新完成工作量證明,這在計算上幾乎不可能達成。
此外,區塊鏈中的「挖礦」本質上就是不斷嘗試不同的隨機數,直到找到一個能讓區塊雜湊值滿足特定條件(例如前導零的數量)的解答。這正是利用了雜湊函數的單向性與不可預測性,讓「付出計算成本」成為取得記帳權的門檻。可以說,沒有雜湊函數,就沒有區塊鏈這項技術。
其他常見應用場景
除了上述三大領域,雜湊函數還出現在許多地方:
防止重複提交與快取鍵:利用雜湊快速比對大量資料是否相同。
三、主流雜湊演算法演進與評測
雜湊演算法的歷史,某種程度上就是一部「攻防對抗史」。每當一個演算法被發現弱點,學界與產業便會推出更強韌的替代方案。了解這段演進,有助於我們在實務上做出正確的選擇。
MD5 與 SHA-1 的殞落
MD5 誕生於 1992 年,曾是最廣泛使用的雜湊演算法之一,輸出長度為 128 位元。在當時,它被認為足以應付各種安全需求。然而,隨著密碼分析技術的進步,研究人員陸續發現 MD5 在碰撞攻擊上的嚴重缺陷。2004 年,中國學者王小雲團隊公開展示了能快速找到 MD5 碰撞的方法,震驚學界。此後,MD5 被徹底排除在安全用途之外。
SHA-1 的命運類似。它由美國國家安全局(NSA)設計、美國國家標準技術研究所(NIST)於 1995 年發布,輸出長度為 160 位元。2017 年,Google 與 CWI 的研究團隊公開了名為「SHAttered」的實際碰撞範例,證明 SHA-1 已不再安全。如今,主流瀏覽器與憑證機構早已停止接受 SHA-1 簽章的憑證。
這兩個案例給了我們一個重要教訓:演算法的安全性並非永恆不變。今天被視為安全的演算法,明天可能因為新的攻擊手法而失效。因此,系統設計時應盡量讓雜湊演算法可替換,避免將演算法硬編碼(hardcode)在不可更新的位置。
SHA-2 家族與 SHA-3
目前最被廣泛採用的安全雜湊演算法,是 SHA-2 家族,包含 SHA-224、SHA-256、SHA-384、SHA-512 等變體。其中 SHA-256 幾乎成為業界標準,被應用於 TLS 憑證、比特幣、軟體簽章等無數場景。SHA-2 至今尚未被發現實用的碰撞攻擊,仍被視為安全可靠。
不過,由於 SHA-2 與 SHA-1 在設計上有部分承襲關係,NIST 在 2007 年便開始舉辦公開競賽,徵求下一代的雜湊標準。2012 年,由 Guido Bertoni 等人設計的 Keccak 演算法脫穎而出,成為 SHA-3 標準。SHA-3 採用了與 SHA-2 完全不同的「海綿結構(Sponge Construction)」,在設計上提供了額外的多樣性,即使未來 SHA-2 出現問題,SHA-3 也能作為可靠的備援。
BLAKE2 與 BLAKE3 等現代高效能演算法
近年來,除了 NIST 標準之外,社群也推出了許多效能更優異的雜湊演算法。BLAKE2 是其中之一,它在設計上參考了 SHA-3 競賽的入圍作品 BLAKE,並針對現代處理器架構進行最佳化,在多數平台上比 SHA-256 快上數倍,同時保有同等的安全性。BLAKE2 又被拆分為 BLAKE2b(適用於 64 位元平台)與 BLAKE2s(適用於 32 位元平台)兩種版本。
BLAKE3 則是更進一步的演進,它結合了 BLAKE2 與 Merkle 樹結構,支援高度平行化計算,並內建了可變輸出長度、金鑰化雜湊與金鑰衍生等功能。對於需要大量雜湊運算的應用,例如內容定址儲存、檔案校驗工具,BLAKE3 提供了極具吸引力的效能優勢。
以下為幾種常見雜湊演算法的簡單比較:
SHA-1:160 位元輸出,已被實際碰撞,不應再用於安全場景。
SHA-256:256 位元輸出,目前主流安全標準,相容性最佳。
SHA-3:結構獨立於 SHA-2,適合需要演算法多樣性的場景。
四、實務應用與開發建議
了解演算法的理論之後,真正的挑戰在於如何把它們正確地用進產品裡。錯誤的實作方式往往比選擇較弱的演算法更危險,因為它會讓原本安全的機制形同虛設。
如何正確選擇雜湊演算法
選擇雜湊演算法時,應該先釐清用途。若是一般性的資料完整性驗證與數位簽章,SHA-256 是安全且相容性最好的選擇;若需要更長的輸出或更高的安全餘裕,可考慮 SHA-384 或 SHA-512。若追求效能,BLAKE2 或 BLAKE3 是值得評估的選項,但須注意其在各語言與平台的支援度。
至於密碼儲存,則絕對不能直接使用 SHA-256 這類通用雜湊函數。原因在於這類函數設計目標是「快」,攻擊者每秒可以嘗試數十億次,對弱密碼而言極度危險。密碼儲存應採用專門的密碼雜湊演算法,例如 Argon2、bcrypt 或 scrypt,這些演算法刻意設計成計算緩慢且記憶體密集,能有效抵禦離線暴力破解。
加鹽、密鑰拉伸與 Argon2 的實作要點
在實作密碼儲存時,以下幾點是開發者必須留意的關鍵:
常見誤用與迷思
在實務中,我們經常看到以下幾種雜湊誤用,值得特別提醒:
第一,「雜湊等於加密」的誤解。有些人會說「這段資料已經被雜湊加密了」,這種說法在技術上是錯誤的。雜湊不可還原,因此不能用來保護需要取回的資料。若你的應用需要還原明文,就應該使用對稱式加密(如 AES-GCM),而非雜湊。
第二,用雜湊值作為「加密密鑰」。雖然雜湊函數確實常用於金鑰衍生(KDF),但這需要專門的設計,例如 HKDF,而非直接把密碼雜湊一下就當作 AES 金鑰使用,否則可能因熵不足而降低安全性。
第三,忽略時序攻擊(Timing Attack)。在比對雜湊值時,若使用一般字串比較函式,可能在遇到第一個不同的字元時就回傳,攻擊者可藉此逐步推測正確摘要。正確做法是使用「常數時間比較」函式,如 Python 的 hmac.compare_digest。
第四,雜湊長度迷思。雜湊值越長不一定越好,重點在於演算法本身的安全性與抗碰撞能力。SHA-256 已提供 128 位元等級的抗碰撞安全,對絕大多數應用而言已綽綽有餘。
五、結語:雜湊函數是信任的數學基礎
回顧整篇文章,我們從雜湊函數的基本定義與核心特性出發,探討了它在密碼儲存、數位簽章、區塊鏈等領域的關鍵角色,並審視了 MD5、SHA-1 到 SHA-3、BLAKE3 等演算法的演進與優劣,最後回到實務層面,分享了正確選型與安全實作的建議。
雜湊函數之所以重要,在於它用極其精簡的數學機制,解決了資訊安全中最根本的信任問題:我如何確認這段資料就是我認為的那段資料?我如何確認這個檔案沒有被竄改?我如何在不儲存密碼的情況下,仍能驗證使用者身分?雜湊函數讓這些問題有了優雅且高效的解答。
對於軟體開發者而言,理解雜湊函數不只是背下幾個演算法名稱,更是建立一種安全思維:知道什麼時候該用雜湊、什麼時候該用加密,知道哪些演算法已經過時,知道加鹽與密鑰拉伸為什麼不可或缺。在資安威脅日益複雜的今天,這些知識將直接影響你產品的防護能力。
最後,技術持續演進,今天安全的設計,明天可能出現新的破口。建議讀者持續關注 NIST、OWASP 等權威機構的建議,並在專案中採用經過社群驗證的函式庫與標準。唯有保持警覺、持續學習,才能讓雜湊函數這道看不見的防線,真正守護使用者的資料安全。
希望這篇文章能為你在軟體加密與雜湊函數的學習路上,提供一份完整而實用的參考。若你對相關主題有興趣,也歡迎持續關注本站的軟體評測與資安技術專欄。