很多人很容易把加密和雜湊搞混,利用這篇文章說明一下兩者的區別。

前言

其實雜湊 (Hash) 的部份,本來是打算放在 如何區分加密、壓縮、編碼 這篇一起講。但在撰寫的過程中發覺雜湊跟其他三者相比起來的差異性較大,一起講其實蠻突兀的,不太好比較。而且我自己目前看到的狀況是,雜湊比較容易跟加密搞混,所以才獨立出這篇來講一下雜湊與加密的關係。

你可能或多或少都有看過或聽過「MD5 加密」、「MD5 解密」、「SHA-1 加密」、「SHA-1 解密」、「雜湊加密演算法」。但 MD5 和 SHA-1 實際上並不是加密演算法,而是雜湊演算法。究竟加密跟雜湊到底有什麼不一樣,又該如何區分,這篇會簡單講解一下。

因為加密的部份已經在 如何區分加密、壓縮、編碼 這篇提過了,所以就不重述,還不清楚的人歡迎點擊上述文章連結前去察看。以下會先講雜湊的特性,再講雜湊跟加密的區別。


雜湊 (Hash)

其實雜湊在一些壓縮演算法或者排序演算法也都有用到,
但這邊只就資訊安全相關的部份進行討論。

  • 特性
    • 無論原文的內容長短,透過雜湊演算法運算完的輸出都會是固定的長度,即輸出的長度不受原文長度影響。
    • 雜湊演算法的輸出又被稱做「雜湊值」(Hash Value)。
    • 不同雜湊演算法輸出的雜湊值長度可能相同。
      • 無法用雜湊值長度來完全斷定使用哪種雜湊演算法。
      • MD2, MD4, MD5 輸出長度皆為 128 bits,通常用 32 個十六進位數表示。
      • SHA-0, SHA-1 輸出長度為 160 bits,通常用 40 個十六進位數表示。
    • 兩個輸入的內容即便只差一個字,雜湊演算法產生的兩個輸出內容卻會差非常多,可以明顯區別。
    • 相同的內容作為相同雜湊演算法的輸入,得到的輸出必定一樣。
    • 不同的內容作為相同雜湊演算法的輸入,得到相同輸出的機率極低。
      • 注意,是極低,不是不可能。
      • 雜湊碰撞 (Hash Collision) 的資安攻擊手法跟這個有關。
    • 無法將雜湊演算法的輸出解回原本的輸入,雜湊是單向的。
      • 但因為相同輸入會得到相同輸出,所以最常見的破解方法就是透過 brute-force 的方式,用程式把各種可能的輸入都餵給雜湊演算法,得到輸出後,把輸入跟輸出以及所使用的雜湊演算法記起來,成為一張對應表(被稱做 rainbow table,彩虹表)。
      • 然後拿雜湊值去其使用之雜湊演算法的 rainbow table 找尋輸入值,因為 rainbow table 是可以一直累積的,所以理論上來說,只要 rainbow table 夠大的話,就能夠找到原始的輸入值。
      • 所以資安實務上會再為原始資料加入 salt 之後,才會丟給雜湊演算法運算,獲得加了 salt 以後的雜湊值。
        • salt 基本上就是額外加入的字串,可以用固定的規則改變原本的輸入值。
        • 這樣的好處是,就算被破解了,破解的人拿到的字串仍然不會是密碼,拿去登入是不會成功的。
        • 但在比對使用者輸入的密碼時,一樣可以加了 salt 之後再進行雜湊去比對,仍然可以驗證密碼是否正確,而安全性會增加。
  • 用途
    • 檔案校驗碼(Checksum)
      • 用來快速判斷檔案是否和原本相同。
      • 有在論壇下載過檔案的人應該都很常見到一長串 MD5 或 SHA-1 驗證碼,就是用來讓你快速檢查你下載的檔案裡頭的內容,是不是跟上傳者上傳的檔案一樣。
      • 不一樣的話可能就是你載錯檔案、檔案有毀損或檔案被人加料了。
    • 不需要被還原的資料
      • 例如:避免明文儲存使用者密碼
        • 避免直接儲存使用者的明文密碼,除了避免資料庫外洩時,攻擊者無需進一步運算就可以直接得到明文密碼外,一方面也是尊重使用者,因為正常情況下只有使用者知道自己的密碼。
        • 要簡單判斷網站有沒有明文儲存你的密碼最簡單的兩個方法:
          • 寄信給你的時候有沒有直接把密碼寫在內文。
          • 忘記密碼的時候不是要求你或幫你重新設定密碼,而是直接告訴你你的密碼。
        • 但因為相同原文透過相同的雜湊演算法會得到相同的輸出,所以可以在不明文儲存使用者密碼的情況下,確認使用者輸入的密碼是否正確。
  • 雜湊碰撞 (Hash Collision)
    • 上面有提到「不同內容作為同一個雜湊演算法的輸入值,可能得到相同輸出的雜湊值,只是機率極低。」雜湊碰撞就是此狀況的應用。
    • 這在實例上大概是什麼狀況?
      • 帳號密碼
        • 還記得剛剛說到我們用來檢驗使用者密碼是否輸入正確,是透過比對雜湊值是否相同來作為依據嗎?
        • 透過雜湊碰撞,攻擊者可以不必知道你的密碼,只要找到某一個輸入,透過同一個雜湊演算法會得到相同的輸出雜湊值,便可讓程式認為攻擊者輸入了正確的密碼。
      • 下載檔案
        • 透過雜湊碰撞,攻擊者可能可以提供一個和你想下載的檔案完全不同且惡意的檔案,因為算出來的雜湊值相同,讓你放心地開啟後進而遭受攻擊。
      • 網站的加密憑證(TLS/SSL)
        • 許多網站的加密憑證簽署過程都有涉及雜湊,所以一旦可以進行碰撞,攻擊者就有機會偽造加密憑證。
    • 現今說的某個雜湊演算法已經不夠安全,基本上指的是:「透過某些方法:可能是發現了雜湊演算法設計上的缺陷、硬體進步導致運算速度變快,使攻擊者在可以接受的時間內,即可找到雜湊碰撞。」
    • 理論上來說,所有雜湊演算法都是可以進行雜湊碰撞的,所以安不安全是在於運算雜湊碰撞所需的時間成本問題。
    • 關於雜湊碰撞的成本,可以參考這篇 2017 年 Google 正式破解 SHA-1 的報導: 九百萬兆次演算實現碰撞!Google 攻破了最重要的加密技術 - INSIDE
    • 等到運算能力超強的量子電腦普及之後,又將會迎來一場不同的局面,到時勢必又有許多資安相關的演算法會被淘汰。當然也會有新的演算法被發明出來,已經有許多資安專家在針對量子電腦領域設計其專用的資安相關演算法了,這裡就不詳述了,怕這篇文章太過發散。
    • 小提醒:「雜湊碰撞」跟中國資安用語的「撞庫」不同。
      • 所謂的「撞庫」,是指當某個服務的使用者密碼外洩,攻擊者拿這個服務外洩的帳號密碼去嘗試登入其他服務。(因為很多人都會在不同服務使用相同的帳號密碼。)
  • 常見演算法
    • SHA 系列
      • SHA-0
        • 不安全。
      • SHA-1
        • 不安全。
      • SHA-2
        • 根據輸出長度不同,可分為 SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256
      • SHA-3
        • 根據輸出長度不同,可分為 SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256
    • MD 系列
      • MD2
        • 不安全。
      • MD4
        • 不安全。
      • MD5
        • 不安全。
    • BLAKE 系列
      • 此系列算是近幾年才設計出來的,號稱加密速度比 SHA 系列和 MD 系列都快且安全。
      • BLAKE
        • 2008 年提出
      • BLAKE2
        • 2012 年提出
      • BLAKE3
        • 2020 年提出
  • 結論
    • 就是一串拿來做檢查的字串,但根據使用需求可以有不同的用途。

所以,為什麼雜湊不是加密?

我個人認為雜湊和加密很容易被人搞混的原因,主要是因為雜湊和加密通常是一起使用的,常常被拿在一起講,加上得到的輸出都是一串無意義的字串,所以久而久之就搞混了。

但其實可以透過以下幾點來區分:

  • 加密需要密鑰,且可以透過解密得到原文。(加密可逆)
  • 雜湊不需密鑰,無法逆向解出原始輸入。(雜湊不可逆)
    • 雖然可以透過額外儲存的 rainbow table 來找尋原始輸入,但彩虹表是預先計算並儲存下來的,而不是雜湊演算法本身的設計。
  • 舉例
    • 今天如果我拿到一串密文,我是有辦法透過解密,得到原始的明文的,而且如果使用非對稱式加密的話,我甚至還可以驗證傳送方是不是本人(是否有被進行中間人攻擊)。
      • 雜湊演算法在這裡也會被使用,通常會被拿來檢驗傳送的訊息是否有被更改過。
      • 傳送方附上原始訊息經過某個雜湊演算法得出的雜湊值,接收方在解開這個訊息之後,會透過相同的雜湊演算法來驗證。
    • 但如果是拿到一串雜湊值的話,理論上是無法逆向得到原始的明文的,根本無法拿來做資料的傳遞。

所以別再說出「MD5 加密」、「MD5 解密」、「SHA-1 加密」、「SHA-1 解密」之類的話啦!


小測驗

如果這兩篇有看懂的話,應該就可以理解這個 tweet 在講什麼:

pkcs7 簽章使用 RSA 加密演算法對資料的 SHA256 雜湊值簽章,台灣的金融機構習慣對這簽章做 base64 編碼來避免古早用 Cobol 的系統以 ASCII 字碼接收而產生所有資料第 8 bit 都是 0 而引起的驗證錯誤。


參考資料


Share


Donation

如果覺得這篇文章對你有幫助, 除了留言讓我知道外, 或許也可以考慮請我喝杯咖啡, 不論金額多寡我都會非常感激且能鼓勵我繼續寫出對你有幫助的文章。

If this blog post happens to be helpful to you, besides of leaving a reply, you may consider buy me a cup of coffee to support me. It would help me write more articles helpful to you in the future and I would really appreciate it.


Related Posts