加密是什麼呢?為什麼要加密?關於加密的基本觀念

加密是什麼呢?為什麼要加密?

前言

什麼是加密呢?這是一個很有趣的議題,剛好前陣子發生了一點事情,所以就順勢生這一篇文章,就讓我們來聊一下何謂加密。

加密是什麼呢?

一開始我們先來了解一下何謂「加密」吧!

簡單來講,加密的定義就是將一段「明文」轉換成「密文」的過程,而這個過程就是「加密」。

而明文就是你可以直接閱讀的文字,例如:

這是一段文字,目前是明文形式

而密文就是你無法直接閱讀的文字,例如將上述文字變成了以下:

7d4c8581949ad44c6376a08fb4691e9f8e66eda501276db3d9af9fc0a6038036e88589ecb4a4aca910a704d36c10eedf

加密的過程基本上會使用到「密鑰」,這樣子當你想要解密的時候,就必須要有相對應的密鑰,才能夠將密文轉換回明文。

為什麼要加密?

首先我們先舉例一個場景,假設你有一個網站,而這個網站有一個登入系統,當你登入的時候,你會輸入你的帳號密碼,而這個帳號密碼就會被傳送到伺服器上,而伺服器會將你的帳號密碼與資料庫裡面的資料做比對,如果比對成功,就會回傳一個登入成功的訊息,如果比對失敗,就會回傳一個登入失敗的訊息。

那麼問題來了,我們如果要登入時,我們的伺服器,也就是資料庫中必定會需要儲存我們的帳號密碼,那麼如果有一天,我們的資料庫被駭客入侵了,那麼我們的帳號密碼就會被駭客拿走,這樣子就會造成很大的資安問題。

因此通常比較敏感的資料,例如:密碼,我們就會使用加密的方式來儲存,這樣子就算是被駭客拿走了,也不會直接看到我們的密碼,而是看到一串亂碼,這樣子就會比較安全。

Note
當然,如果你的金鑰也被拿走了,那麼就沒有辦法保護你的資料了,因此金鑰的保管也是很重要的一環。

那麼對於加密的方式,我們可以分成兩種:

  • 對稱式加密(Symmetric-key algorithm)
  • 非對稱式加密(Public-key cryptography)

而加密的過程通常會使用各種不同的加密演算法,例如:AES、RSA 等等,實際上這些演算法都是在做「加密」與「解密」的過程,而這些演算法的運作方式,就是透過「金鑰」來做加密與解密的過程。

對稱式加密(Symmetric-key algorithm)

首先我們先來聊聊第一個,也就是對稱式加密,所謂的對稱式加密,就是加密與解密使用同一個金鑰,假設我們的金鑰是「IsRayNotArray」,那麼我們在做加密與解密的時候,都會使用這個金鑰,這樣子就可以將明文轉換成密文,也可以將密文轉換成明文,概念如下圖:

對稱式加密

那麼傳輸過程中是會把金鑰也一起傳輸嗎?這樣子不就會被駭客拿走了嗎?理論上是的沒錯,否則接收訊息方就無法解密,因此假設好死不死,你在第一次傳輸「共同金鑰」的時候,就被中間人攔截了,那麼你的加密就失去了意義,而這也是對稱式加密的缺點

金鑰外流

非對稱式加密(Public-key cryptography)

那麼非對稱加密就有一點特別了,所謂的非對稱式加密,也就是使用了兩把鑰匙,分別是「Public Key」與「Private Key」,而這兩把鑰匙是成對的,那這兩個鑰匙有什麼不同呢?

基本上我們在使用非對稱式加密的時候,會將「Public Key」傳給對方,而「Private Key」則是自己保留,而當對方要傳送訊息給你的時候,就會使用你的「Public Key」來加密,而你則是使用「Private Key」來解密,這樣子就可以達到加密的效果,而這個過程就是非對稱式加密,概念如下圖:

非對稱式加密

從上面的圖我們可以發現一件事情,我們的金鑰是透過右邊的人在本地(自己電腦)生成,並且將「Public Key」傳給左邊的人,而左邊的人則是使用「Public Key」來加密訊息,並且傳送使用「Public Key」加密過的訊息給右邊的人,而右邊的人則是使用「Private Key」來解密訊息,這樣子就可以達到加密的效果,使用這個方式我們可以避免共通金鑰被攔截的問題,因為我們的「Private Key」是在本地生成的,並且不會被傳送出去,因此就算是被攔截「Public Key」也不會有問題,因為無法解密。

那麼以上就是一個基本的對稱加密與非對稱加密的概念,而實際上我們在使用的時候,會使用到各種不同的演算法,例如:AES、RSA 等等,而這些演算法的運作方式,就是透過「金鑰」來做加密與解密的過程。

Note
GitHub 的 SSH 就是使用非對稱式加密的方式,當你在 GitHub 上面新增 SSH 金鑰的時候,GitHub 會將你的「Public Key」儲存起來,而當你要推送的時候,GitHub 就會使用你的「Public Key」來加密,而你則是使用「Private Key」來解密,這樣子就可以達到加密的效果。

加密概念總結

那麼這邊我們也做一下概念總結,加密的方式主要有兩種:

  • 對稱式加密(Symmetric-key algorithm)
  • 非對稱式加密(Public-key cryptography)

底下還會細分加密的演算法,例如:AES、RSA 等等,而這些演算法的運作方式,就是透過「金鑰」來做加密與解密的過程。

因此我們在使用加密的時候,就必須要注意金鑰的保管,否則就會有資安的問題,就算你使用的是非對稱式加密,也是一樣的,因為你的「Private Key」如果外流也是一樣。

那麼問題來了…

「我們前端開發者常常用來與後端溝通的 JWT 呢?JWT 是屬於哪一種加密呢?」

其實 JWT 在運作上確實也是會使用到金鑰與演算法的概念,但認真來講 JWT 並不是加密,而是簽章的過程。

為什麼這樣說呢?因為 JWT 主要是用來驗證資料之間的傳輸正確性而非用來保護資料的安全性,因此你通常只會在本地端接收 Token 而不會特別去驗證或解密 Token,你手上也不會持有金鑰,因為 JWT 本身就只是拿來驗證資料的正確性而已,因此你不需要去驗證或解密,而是直接拿來用就好了,驗證就給後端去做就好了(更不用說前端沒有秘密)。

關於 Base64 編碼

前面聊了加密後,接下來就要聊一個東西,也就是就是「編碼」,編碼其實跟加密很容易被混淆,尤其是…Base64

為什麼會特別提到 Base64 呢?因為其實 Base64 是最容易被誤會的,這邊請熟記一件事情

「Base64 並不是加密,而是編碼」

為什麼這樣說呢?因為 Base64 在運作上是有跡可循的,什麼意思呢?就是說 Base64 會將原本的資料,透過一個特定的規則,將資料轉換成另一種形式,而這個轉換的過程是可以逆推的,也就是說,你如果了解 Base64 的規則,就可以將 Base64 的資料轉換回原本的資料。

很難懂吧?我們就來舉例一下「Ray」好了,底下這邊是一張標準的 Base64 索引表

來源:維基百科

接著我們要如何轉換呢?首先我們要找到 ASCII 碼,如下圖:

ASCII

以「Ray」這三個單字所對應的 ASCII 碼為例的話,就會是以下:

  • R:82
  • a:97
  • y:121

Note
主要是看 Decimal(Dec) 這一欄。

接著 Base64 是使用二進位的方式來做轉換的,因此我們要將這三個數字轉換成二進位,這三個數字轉換成二進位的結果如下:

  • R:82 => 01010010
  • a:97 => 01100001
  • y:121 => 01111001

Note
基本上二進位是採用八位元的方式來做轉換,因此我們會將這三個數字補齊成八位元。

那麼由於 Base64 是採用六位元的方式來做轉換,因此我們要將八位元的二進位切割成六位元,而這個過程就是 Base64 的規則,所以用表格來呈現就會變成以下

轉換過程

透過上述規則,我們就可以將「Ray」這三個單字轉換成「UmF5」。

那我們該如何驗證呢?我們可以使用線上工具來驗證,例如:Base64

Base64 編碼

我們可以看到結果是一樣的,這樣子就可以驗證我們的結果是正確的。

當然也可以試著將「UmF5」轉換回「Ray」

Base64

透過上述的實際操作,我們就可以發現 Base64 完全是可以逆推出來的,因此如果作為加密保護重要的資料,例如…電子信箱、密碼以及身份證字號是完全不適合的,畢竟只要知道規則,就可以逆推出來,因此 Base64 只適合用來做簡單的編碼,例如:將圖片轉換成 Base64,這樣子就可以直接將圖片嵌入到 HTML 中,而不需要另外載入圖片,這樣子就可以減少一次請求,提升效能(但是會增加 HTML 的大小)。

那麼這一篇也差不多到這邊了,希望這一篇文章有幫助到你哩~

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ