密碼學中的 Encode、Encrypt、Hash 的差別在哪裡?

古古

2024/12/10


在密碼學中,Encode、Encrypt、Hash 可以說是三大基礎概念,並且也是後端工程師必備的密碼學知識,因此這篇文章就會詳細來介紹什麼是 Encode、Encrypt、Hash,以及比較他們之間的區別。

本文為 JWT 系列文之一,如果你對 JWT 的其他文章有興趣,也可以直接點擊下列連結跳轉到該文章(不過建議還是按照順序閱讀,才會有最佳的閱讀體驗):

  1. Session 和 JWT 的差別在哪裡?
  2. 密碼學中的 Encode、Encrypt、Hash 的差別在哪裡? (本文)
  3. JWT 是什麼?一次搞懂 JWT 的組成和運作原理
  4. JWT 是如何實作「數位簽名」的?揭秘 signature 的面紗

Encode、Encrypt、Hash 簡介 #

在密碼學中有三大概念,分別是:

  1. Encode(編碼)
  2. Encrypt(加密)
  3. Hash(雜湊)

以下分別介紹如何透過這三種不同的方法,去對數據做不同的處理。

什麼是 Encode(編碼)? #

所謂的 Encode(編碼),就是「數據可以直接被編碼」,並且中間「不需要」任何的密鑰參與。

像是在下面的例子中,左邊的原始字串 123,就可以被 Encode(編碼)成右邊的 gg2oGVzdD,而右邊的 gg2oGVzdD,他也是可以直接被 Decode(解碼)回原始的字串 123 的。

因此在 Encode 和 Decode 的過程中,是不需要任何的密鑰,「所有人」 都可以輕易的 Encode 和 Decode。

而一般在實務上,最常見的 Encode 演算法為「Base64」,像是在這個 Base64 Encode 的網站中,只要在上面輸入 test123,下面就會出現 Encode 過後的結果 dGVzdDEyMw==

而這時如果大家複製一下下方的結果 dGVzdDEyMw==,然後點擊左邊的 Decode 連結 (跳轉到 Decode 的頁面),然後將剛剛的結果 dGVzdDEyMw== 貼在上面的話,這時候就可以直接將這個結果 Decode 回原始的字串 test123

所以對於 Encode 和 Decode 來說,他們完全不需要密鑰的參與,也可以對數據進行「編碼和解碼」,因此所有人都可以針對某一筆數據進行 Encode 和 Decode。

也因為如此,大家在使用 Base64 去 Encode 數據時,一定要注意這個數據是沒有被加密過的,所以所有人都有能力將他 Decode 回原始的字串!!一定要小心!!!

所以下次當你看到有人在網路上隨意散播使用 Base64 Encode 的數據時,你完全可以大膽的將他 Decode,就可以得到原始的字串,因此千萬不要再誤解 Base64 很安全了🥹,他真的就只是一個編碼的工具而已,完全沒有任何加密的成分在裡面!

補充:Encode 其實嚴格上來說不算加密,因為他只是改變數據的呈現方式,完全沒有加密可言,但口語上有時候還是會把 Encode 歸類成加密,因此才放在這裡一起介紹。

什麼是 Encrypt(加密)? #

了解了 Encode 之後,接下來我們可以來看一下 Encrypt 的相關介紹。

所謂的 Encrypt(加密),就是「將數據加密成密文」,所以透過 Encrypt 加密過後的數據,他可以說是非常安全的。

而在 Encrypt 的世界中,又可以再細分成兩種加密方式,分別是:

  • 對稱加密
  • 非對稱加密

所以以下針對這兩種加密方式來介紹。

什麼是對稱加密? #

在對稱加密中,只會有「一把」密鑰存在,因此不論是加密還是解密,就統統是用這把密鑰來進行。

舉例來說,左邊的原始的字串 123,他就可以透過這把密鑰(或是簡稱為這把 key),加密成右邊的 gg2oGVzdD,而右邊的 gg2oGVzdD,他也可以透過這把密鑰,解密回原始的字串 123

所以在對稱加密中,就只會存在「一把」密鑰,因此不管你是要加密還是解密,統統就是透過這把密鑰進行。

也因為在對稱加密中只有一把密鑰存在,所以這把密鑰必須要好好的保護,絕對不可以洩漏,一但密鑰洩漏,駭客就可以透過這把密鑰解密出原始的字串,因此在對稱加密中,保護密鑰是非常重要的任務!

什麼是非對稱加密? #

而不同於對稱加密,在非對稱加密中,則是會有「兩把」密鑰存在。

在這兩把密鑰中,其中一把會叫做「公鑰」(也就是 Public Key),另一把則叫做「私鑰」(也就是 Private Key),因此在非對稱加密中,就是由「公鑰」和「私鑰」共同配合,對數據進行加密和解密。

所以這兩把密鑰,他們的特性如下:

  • 公鑰(Public Key):公開的,可以複製好幾份,廣發給所有人
  • 私鑰(Private Key):私有的,必須要好好的保護,不可以洩漏

並且在非對稱加密中,有一個很神奇的運作邏輯,也就是:

  • 「公鑰」 所加密的數據,只能夠由 「私鑰」 解密
  • 「私鑰」 所加密的數據,只能夠由 「公鑰」 解密

所以換句話說的話,就是 「由其中一把鑰匙所加密的數據,只能夠用另一把鑰匙來解密」,這就是「非對稱加密」的運作方式。

也由於非對稱加密的神奇特性(其中一把加密的數據,只能用另一把解密),所以在 JWT 中的「數位簽名」,實際上就是用非對稱加密所實作的。甚至不止 JWT,像是區塊鏈中的數位簽名,他背後也是用非對稱加密實作的(不如說只要是扯到「數位簽名」或是「數位簽章」這個概念,底層都是同一套,都是用非對稱加密實作)。

所以在了解 JWT 的「數位簽名」是如何實作的之前,建議大家一定要先了解「非對稱加密」的運作邏輯(也就是其中一把加密的數據,只能用另一把解密),這樣子後續在了解 JWT 的相關知識時,才能夠知道他底層的運作邏輯為何。

什麼是 Hash(雜湊)? #

在了解了 Encrypt 中的「對稱加密」和「非對稱加密」之後,最後我們也可以來看一下 Hash 的相關介紹。

所謂的 Hash(雜湊),就是「單方面的將數據轉換成亂碼(或稱為 Hash Value,雜湊值)」,並且這個 Hash Value,他是「不能夠」轉換回原始的字串的。

舉例來說,左邊的原始字串 123,他可以被 Hash 成右邊的亂碼 gg2o861kdn5(又稱為 Hash Value,雜湊值),但是我們卻沒辦法將右邊的亂碼 gg2o861kdn5,轉換回原始的字串 123

所以在 Hash 的世界中,所有的數據只要被 Hash 過,就再也沒辦法轉換回原始的數據,就算老天來也沒用,世界上沒有人(包含駭客和你自己)有能力將 Hash Value 轉換回原始的數據。

補充:Hash 真的沒辦法被破解嗎? #

從根本的邏輯上,只要一個數據被 Hash 過,那我們是真的沒有辦法將這個數據轉換回原始的字串,但是!!駭客就想到一招破解的方式:「既然我沒辦法將數據轉換回來,那我乾脆提前做一張很大很大的表格,提前記錄 什麼樣的數據 會轉換成 什麼樣的亂碼 不就好了?」

舉例來說,駭客可以提前計算出 123 這個字串會被 Hash 成 gg2o861kdn5456 這個字串會被 Hash 成 aaaa777k3nt…等等的結果。因此當駭客發現某一筆被 Hash 過的值是 aaaa777k3nt 時,駭客就只要回來查詢這張表格,就可以馬上找出 aaaa777k3nt 的原始字串是 456,因此就可以用這張很大的表格,來破解被 Hash 過後的值。

原始字串 Hash 過的值
123 gg2o861kdn5
456 aaaa777k3nt

因此像是常見的 Hash 演算法「MD5」,駭客就已經透過 「彩虹表(Rainbow Table)」 反向破解出他的所有可能組合了,因此在實務上,建議大家選擇更可靠的 Hash 演算法(像是 BCrypt)來實作,才能夠避免駭客的攻擊。

補充 2:我還是很想用 MD5,真的沒辦法了嗎? #

即使 MD5 已經被駭客的「彩虹表」給反向破解了,但實際上我們還是可以透過一個簡單的補強方法,來強化 Hash 的安全性,這個做法就叫做 「加鹽(salting)」

所謂的加鹽,就是「偷偷在原始的字串中插入一段亂碼」,然後再把這整個字串拿去 Hash,等於是我們為原始的字串偷加了一點調味料(鹽巴),讓他變得不太一樣。

舉例來說,我們就可以在原始的字串 123 中,偷偷加上一點鹽巴 ND3dmEyMzQxM,這樣最後 Hash 出來的結果就會不一樣。

而這種加鹽的做法之所以可以反制駭客,有兩個原因:

  1. 我們可以將中間的「鹽巴」設定成一個很長的字串,只要字串一變長,窮舉法就很難列完所有組合,因此駭客的那張表格就會變得非常非常大,大到駭客難以維護。
  2. 即使駭客運氣好仍舊破解出這個字串 12ND3dmEyMzQxM3,但是駭客也不知道「到底哪一個字母是我們偷加的鹽巴」、「哪一個字母是原始的字串」,因此即使駭客看著手上的 12ND3dmEyMzQxM3 字串時,他也不知道其中的 123 才是真實的原始字串。

所以透過「加鹽(salting)」的方式,我們就能夠大大的提升了 Hash 的安全性了!讚!

補充:現今流行的 Hash 演算法(ex: BCrypt),通常都會自帶加鹽的實作,因此不需要我們再額外手動去為他加鹽,為我們節省許多開發的時間,太讚啦!!

Encode、Encrypt、Hash 總結 #

所以總和上述的介紹,最後來總結一下 Encode、Encrypt、Hash 這三大概念的話:

  1. Encode(編碼):數據可以直接被編碼,並且「不需要」任何的密鑰參與,所有人都可以直接 Encode 和 Decode 數據,非常不安全
  2. Encrypt(加密):使用密鑰將數據加密成密文,安全性高,又可區分為「對稱加密」和「非對稱加密」
  3. Hash(雜湊):單方面的將數據轉換成 Hash Value(又稱為雜湊值)

所以透過這張表格,希望能夠讓大家更了解 Encode、Encrypt 和 Hash 他們之間的差別在哪裡,因此大家後續在使用上,就可以根據自己的需求,決定哪一種方式是最適合你的實作方法了。

補充:本文是擷取自我開設的線上課程 「資安一把罩!Spring Security 零基礎入門」 的內容,如果你想了解更多的資安內容、以及如何應用 Spring Security,歡迎參考課程簡介 (輸入折扣碼「HH202501KU」即可享 85 折優惠)。

結語 #

這篇文章我們介紹了 Encode、Encrypt 以及 Hash 的差別,這三大概念可以說是密碼學的基礎,也是後端工程師必備的密碼學知識,因此建議大家一定要好好了解會比較好!

如果你對後端技術有興趣的話,也歡迎免費訂閱 《古古的後端筆記》電子報 ,每週二為你送上一篇後端技術分享,那我們就下一篇文章見啦!

本文為 JWT 系列文之一,如果你對 JWT 的其他文章有興趣,也可以直接點擊下列連結跳轉到該文章(建議按照順序閱讀,才會有最佳的閱讀體驗):

  1. Session 和 JWT 的差別在哪裡?
  2. 密碼學中的 Encode、Encrypt、Hash 的差別在哪裡? (本文)
  3. JWT 是什麼?一次搞懂 JWT 的組成和運作原理
  4. JWT 是如何實作「數位簽名」的?揭秘 signature 的面紗

免費訂閱《古古的後端筆記》電子報

每週二學習後端技術,和 2700 人一起變強💪