跳到主要內容

← 返回部落格

Base64 是加密嗎?一次搞懂編碼與加密的差別

這是軟體界最常見的誤解之一:有人看到 cGFzc3dvcmQ= 這種字串,就以為資料被「加密」了。其實沒有。Base64 是編碼,不是加密 —— 搞混這兩者會導致真正的資安錯誤。我們來釐清。

這裡給的是證據,不是主張。 把 JWT 官方文件的示範 token 貼進我們的 JWT 解碼器。不提供任何密鑰,它立刻印出:

{ "alg": "HS256", "typ": "JWT" }
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }

那個 token 的內容是 Base64url,而 Base64 是一種傳輸編碼、字母表是公開的 —— 完全沒有秘密參與,所以任何用它編碼的東西,只要有人願意就讀得到。簽章才是唯一需要密鑰的部分,而它防的是篡改,不是閱讀。永遠不要把機密放進 Base64 字串然後說它受保護了。

Base64 到底做了什麼

Base64 把任意位元組用 64 個可列印字元(A–Z、a–z、0–9、+/)來表示。它的用途是傳輸:讓你把二進位或特殊字元透過只能處理文字的通道帶過去 —— email 內文、JSON 欄位、Data URI、JWT 段落等等。

關鍵是,Base64 沒有金鑰、沒有秘密。任何人都能在瞬間解回原文。試試看:把 cGFzc3dvcmQ= 貼進 Base64 工具,立刻就會得到 password

把這個說法變成輸出。下表每一列都經過我們自己的 Base64 編碼器;把右邊任何一個值貼回同一頁、切到解碼,左邊那一欄就原樣回來。整個過程沒有任何密鑰 —— 根本沒有地方放密鑰。

輸入Base64
secretc2VjcmV0
admin:passwordYWRtaW46cGFzc3dvcmQ=
{"role":"admin"}eyJyb2xlIjoiYWRtaW4ifQ==
Hello, World!SGVsbG8sIFdvcmxkIQ==

編碼 vs 加密

編碼(Base64)加密
目的讓資料能安全傳輸讓資料對他人不可讀
金鑰/秘密有 —— 需要金鑰
任何人都能還原?是,輕而易舉否,只有持金鑰者
提供機密性?❌ 否✅ 是

編碼談的是表示方式;加密談的是保密。它們解決完全不同的問題。

第二列不是硬湊的例子。HTTP Basic 認證送的就是這個:admin:password 變成 YWRtaW46cGFzc3dvcmQ=,標頭寫成 Authorization: Basic YWRtaW46cGFzc3dvcmQ=。任何看得到這個請求的人都讀得到密碼,這就是為什麼 Basic auth 只有在 TLS 之上才可以接受 —— 機密性是傳輸層給的,編碼一點都沒給。第三列是同一個錯誤換一套衣服:eyJyb2xlIjoiYWRtaW4ifQ== 看起來不透明,一步就解成 {"role":"admin"},所以 cookie 裡放這種值,等於讓使用者自己發權限給自己。

一個相關概念:雜湊

大家也常把 Base64 跟雜湊搞混。雜湊(如 SHA-256)是單向函數 —— 你無法從結果反推原文 —— 用於完整性校驗與密碼儲存,而非傳輸。想實驗的話,我們的 Hash 產生器會示範同一輸入永遠產生相同的固定長度指紋。

所以有三個不同的概念:

  • 編碼(Base64):任何人可還原,用於傳輸。
  • 雜湊(SHA-256):單向,用於完整性。
  • 加密(AES、RSA…):只有持金鑰者能還原,用於保密。

要避免的資安錯誤

千萬別用 Base64 來「藏」密碼、API 金鑰或任何機敏值。因為它可被輕易還原,對機密提供的保護是。若需要機密性,請用真正的加密(例如傳輸中用 TLS、靜態資料用 AES),並妥善儲存憑證。

判斷一件事是不是加密,有個好用的測試:問「什麼東西必須是祕密的」。對 c2VjcmV0 而言什麼都不是 —— 演算法公開、字母表公開,而且沒有任何密鑰參數需要保護。沒有祕密的加密不是加密,只是同一份資料的另一種拼法。

Base64 適合用在哪

當你確實需要把二進位或特殊資料透過文字通道傳遞時,Base64 很完美:

  • 把小圖片轉成 Data URI 內嵌到 HTML 或 CSS。
  • 檢視或組裝 JWT 的各段落。
  • 在 JSON API 中傳遞二進位內容。
  • 把特殊字元安全地放進某個值裡。

拿它做它擅長的事 —— 表示 —— 需要保密時再用加密。你可以用我們免費、在瀏覽器執行的 Base64 工具(完整支援 UTF-8)來編碼與解碼。