資安基礎 / FIELD NOTE

Base64 不是加密:編碼、加密、雜湊與密碼儲存的實務判斷

Base64 只是換一種表示方式,保密與密碼驗證需要另外設計。延伸資安面試 E03,透過示意圖、比較表與可重算的 Python 範例,補上長度變化、HTTPS 邊界、可信摘要來源,以及專用密碼雜湊、鹽值與成本的實務細節。

Base64 不是加密:編碼、加密、雜湊與密碼儲存的實務判斷封面

「資料變成一串看不懂的字元,是不是就安全了?」

我在資安面試 E03 用三個需求區分編碼、加密與雜湊:換格式、保護原文、比對內容。這篇把選型時還需要問的細節補齊,包括 Base64 為什麼會變長、HTTPS 保護到哪裡、摘要的可信來源,以及密碼驗證紀錄該保存什麼。

先看需求,再選方法

圖 1:資料處理方式的需求判斷;密碼驗證需另外考慮專用方法、鹽值與成本。
需求可用方法是否要還原原文需要留意的條件
讓文字介面接收二進位資料Base64 編碼解碼即可還原位元組沒有保密能力,雙方須採相同格式
保存機密資料,之後還要讀取成熟的加密方案透過對應金鑰解密實作、金鑰管理與竄改偵測都要顧到
核對檔案或資料內容SHA-256 等摘要摘要不是還原工具參考摘要必須可信
驗證使用者輸入的密碼專用密碼雜湊方法不需要取回舊密碼每筆鹽值、成本與驗證紀錄要一起規劃

同一份資料也可能先加密,再用 Base64 表示密文,方便放進文字欄位。保密來自加密;Base64 負責格式。看到一串文字,只能當作調查線索,不能憑外觀斷定裡面是密文、摘要或什麼演算法。

Base64 的長度:先數位元組,不是數中文字

Base64 每三個輸入位元組,通常變成四個輸出字元。若採標準 Base64、保留 = 補位且不插入換行,輸出長度可由下式算出:

輸出字元數 = 4 × ceil(輸入位元組數 ÷ 3)

ceil 是無條件進位。這是依 RFC 的編碼分組推得的長度公式;資料很長時約增加三分之一,小資料受補位影響,比例可能更高。= 是補位記號,不是秘密金鑰。Base64url 使用 -、_ 取代 +、/;能否省略補位要依使用協定,不能任意刪字。RFC 4648,第 3–5 節

原始輸入位元組數Base64 字元數(含補位)相較原始位元組的增加比例
1 個位元組14300%
2 個位元組24100%
3 個位元組34約 33.3%
rulearena!,UTF-8101660%
資安面試範例一,UTF-82128約 33.3%

表格是純 Base64 長度,不含 JSON 欄位、引號、HTTP 標頭等額外資料。「七個中文字」在這個 UTF-8 範例是 21 個位元組,不能把字數直接代入公式。

自己確認一次編碼與解碼

前置條件是已有 Python 3。以下只用標準函式庫與教學字串,不需要安裝套件或連線服務。請將程式存成 base64_demo.py,在終端機執行 python3 base64_demo.py。

import base64

raw = "rulearena!".encode("utf-8")
encoded = base64.b64encode(raw)
restored = base64.b64decode(encoded, validate=True)

print(len(raw), len(encoded))
print(encoded.decode("ascii"))
print(restored.decode("utf-8"))

預期輸出:

10 16
cnVsZWFyZW5hIQ==
rulearena!

validate=True 讓解碼器拒絕不屬於指定字母表的字元。它檢查的是輸入格式,不會證明內容可信,也不會提供保密能力。Python base64 文件

Basic Auth:HTTPS 保護傳輸,日誌仍要另外管

HTTP Basic Auth 將 使用者名稱:密碼 依字元編碼轉為位元組,再做 Base64,放進 Authorization: Basic …。因此拿到該值的人可以按規則解碼;Base64 沒有替帳密上鎖。RFC 明確指出,Basic Auth 本身無法保護敏感資訊,應配合 HTTPS 等保護。RFC 7617,第 2、4 節

實務檢查不能停在「網址有 https」。例如 TLS 在反向代理結束,代理轉送到應用程式的路徑是否也受到保護?除錯紀錄、錯誤追蹤和備份有沒有留下完整 Authorization 值?這些是從保護邊界延伸出的檢查問題。傳輸安全不會自動替已記錄的帳密保密;記錄時應排除憑證內容。

加密還要問:內容被動過,能不能發現?

影片談到演算法與金鑰,我會再補問完整性:收到的密文若被改動,系統能否拒絕它?

AEAD 是同時處理保密與驗證的加密方式,白話說就是「鎖住內容,也檢查內容是否被動過」。例如 AES 的 GCM 模式;成熟函式庫能協助處理這些要求。不能只看到「用了 AES」就認定整體做法安全。OWASP Cryptographic Storage:Cipher Modes

選用方案時,我會把以下問題一起寫進設計:初始化值等參數是否按函式庫要求處理?金鑰由誰存取?備份外洩時,金鑰會不會一起出去?金鑰遺失後,資料是否還能復原?輪替金鑰時,舊資料怎麼讀?

這些問題沒有一個只靠加長密文就能解決。先採成熟方案,再依實際存取與復原需求確認設定。OWASP Cryptographic Storage:Key Management

SHA-256:比的是相同位元組,還要有可信參考值

SHA-256 的摘要是 256 bits,也就是 32 bytes;以十六進位顯示時是 64 個字元。輸入的是位元組,所以文字編碼、換行或一個空白不同,都可能使摘要不同。以下數值是對 UTF-8 教學字串實際計算的結果,沒有額外換行。Python hashlib 文件

教學字串(不是檔案名稱)完整 SHA-256
資安面試範例一59f2b55e1f78d446c326087cfc3010e41fc2602e370d5e88316ad28e5575c8be
資安面試範例二5ce167d13a4a791cb92996d180665dbda1708f0550230c999310a5bb1cf6fc26

可以用下面的程式重算;存成 hash_demo.py,執行 python3 hash_demo.py。

import hashlib

for text in ("資安面試範例一", "資安面試範例二"):
    data = text.encode("utf-8")
    print(text, hashlib.sha256(data).hexdigest())

摘要不同,表示輸入位元組不同。摘要相同則是實務上的強比對依據,但不是所有可能資料之間絕不碰撞的數學保證:固定長度的輸出只有有限種,可能輸入卻更多。「指紋」是幫助理解的比喻,不應解讀成永久唯一。

圖 2:若檔案與參考摘要同時遭替換,比對仍可相符;圖中摘要僅節錄前 16 個十六進位字元。

還有更直接的限制:任何人拿到檔案,都能自己算摘要。假如檔案與旁邊的摘要都由同一個未核實來源提供,兩者相符也不能證明它就是原廠檔案。這是依摘要可重新計算的性質所作的推論;比對之前,應先確認官方下載入口與參考值的取得途徑。

在 SOC 調查中,已知惡意樣本的摘要可用來找相同內容。沒有命中卻不能判定安全,因為內容變動就可能產生不同摘要;命中也要核實情資品質與事件脈絡。摘要比對回答的是一個明確問題,不是所有安全問題。

密碼儲存:專用方法、鹽值、成本缺一不可

使用者登入時,系統通常只需要驗證輸入,不需要取回舊密碼。影片已說明單次 SHA-256 算得太快,資料庫外洩後會讓大量猜測成本偏低;加上鹽值也不會把快速摘要自動變成適合密碼的方案。

新系統可優先評估 Argon2id;無法使用時再評估 scrypt。舊系統與合規需求可能影響 bcrypt、PBKDF2 的選擇,應查最新建議與所用函式庫的限制。OWASP Password Storage

Argon2id 的參數包含記憶體、執行輪數與平行度。它們不是同一件事:增加平行度不等於增加輪數,也不保證猜測一定更慢。參數應在目標伺服器上量測,兼顧登入延遲、記憶體和同時登入量。RFC 9106,第 3.1、4 節

圖 3:註冊時建立驗證紀錄,登入時交給函式庫 verify;欄位只是概念示意,不是自訂儲存格式。

驗證紀錄需要包含演算法、版本、成本、鹽值與計算結果,才能在下次登入重現驗證條件。依函式庫的標準編碼格式保存,使用它提供的驗證方法;不要自己拼接字串並當成完整認證系統。Argon2 的輸入定義也涵蓋版本、鹽值與成本參數。RFC 9106,第 3.1 節

鹽值、Pepper 與金鑰是三種不同角色

項目用途是否保密存放與維護重點
鹽值 Salt讓不同驗證紀錄分開計算不必保密每筆隨機產生,與驗證紀錄保存
Pepper密碼保護的額外秘密必須保密與密碼資料庫分開管理;是額外防護,不取代鹽值
解密金鑰還原對應的密文必須保密控制存取、備份、復原與輪替

Pepper 若外洩,常需要使用者重新輸入或重設密碼才能更換;導入前要想好這項維運成本。OWASP Password Storage:Peppering

登入限速與 MFA(除了密碼,再要求另一項驗證)是線上防護;資料庫外洩後,在外部重算密碼的情境,仍要靠儲存方法提高每次猜測的代價。成本升級也需要遷移策略:成功驗證後,用當次輸入重建較新的驗證紀錄;忘記密碼則走重設流程,不去「解密」舊摘要。OWASP Password Storage:Upgrading the Work Factor

面試回答:把目的和限制一起說出來

可以這樣回答:

我會先確認處理資料的目的。格式相容可以用 Base64 等編碼;需要保密且之後讀回原文,使用成熟加密方案並管理金鑰;要核對內容,用摘要並確認參考來源可信。密碼驗證另選專用密碼雜湊方法,搭配每筆鹽值與適當成本。資料變難讀,不等於已受到安全保護。

接著練習三個追問:密文用 Base64 放進 JSON,保密來自哪一步?下載檔案與摘要都被換掉,為什麼比對仍相符?資料庫裡看不到原密碼,為什麼還要檢查使用的演算法與成本?能回答這些條件,才算把定義用進實務。

參考資料

技術查核日期:2026-10-08。程式與數值使用本文教學字串在本機驗證;不使用真實帳密或公司資料。

ARTICLE IMAGE圖片放大檢視