Base64 URL 安全編碼:它是什麼以及為什麼重要
什麼是 Base64 URL 安全編碼?
Base64 URL 安全編碼(也稱為 Base64url)是標準 Base64 的變體,它將在 URL 和檔案名稱中具有特殊意義的字元替換為安全的替代字元。標準 Base64 使用 + 和 / 作為其 64 字元字元集的一部分,再加上 = 作為填充,而這三個字元在 URL、查詢字串和檔案路徑中都會造成問題。
Base64url 透過兩個簡單的替換解決了這個問題:
| 標準 Base64 | URL 安全 Base64 |
|-----------------|-----------------|
| +(加號) | -(減號) |
| /(斜線) | _(底線) |
| =(填充) | 省略(通常) |
為什麼標準 Base64 會破壞 URL
當包含 + 或 / 的 Base64 編碼字串出現在 URL 中時,瀏覽器和伺服器的行為會變得不可預測。
+ 的問題
在 URL 查詢字串中,+ 字元被解讀為空格。這一行為源自 application/x-www-form-urlencoded 規範,會導致解碼後的資料中包含非預期的空格。
例如,像 Pj4+Pz8/Pw== 這樣的 Base64 字串包含 + 字元。如果它出現在 URL 參數 ?token=Pj4+Pz8/Pw== 中,伺服器會收到 ?token=Pj4 Pz8/Pw==——+ 變成了空格。
/ 的問題
在 URL 路徑中,/ 字元是路徑分隔符號。像 ab/CD+Ef== 這樣的 Base64 字串包含的 / 會被解讀為目錄層級。如果它出現在 URL 區段中,客戶端和伺服器都可能誤解其結構。
= 的問題
= 字元在查詢字串中用於鍵值對。?data=SGVsbG8= 中的尾隨 = 可能產生歧義——這個 = 是 Base64 填充的一部分,還是查詢參數語法的一部分?
雖然百分比編碼可以解決這些問題(+ 變成 %2B,/ 變成 %2F),但它會增加字串長度並讓除錯更加困難。Base64url 是更簡潔的解決方案。
Base64url 的運作方式
Base64url 正式定義於 RFC 4648 第 5 節。它使用與標準 Base64 完全相同的演算法——3 位元組變成 4 個字元——但在字元集的位置 62 和 63 處進行了單字元替換:
- 字元集索引 62:
+→-(減號) - 字元集索引 63:
/→_(底線)
填充(=)通常會被移除,因為解碼時可以從字串長度推斷出來。Base64url 字串始終是有效的 URL 組成部分,無需額外的跳脫處理。
轉換前後對照
以下是相同二進位資料在兩種格式中的樣貌:
標準: Pj4+Pz8/Pw==
URL 安全:Pj4-Pz8_Pw
Base64url 的應用場景
JSON Web Token(JWT)
JWT 是 Base64url 最顯著的使用者。每個 JWT 由三個部分組成——標頭(header)、酬載(payload)和簽章(signature)——每個部分都經過 URL 安全 Base64 編碼並以點號分隔:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNqP0m2iTgCjD0
請注意其中的減號和底線——沒有加號或斜線。如果 JWT 使用標準 Base64,當 Token 作為 URL 參數傳遞時(這是它們在網頁應用程式中最常見的使用方式)就會失效。
OAuth 和 OpenID Connect
OAuth 2.0 和 OpenID Connect 都依賴 JWT 來處理存取 Token 和 ID Token,這使得 Base64url 編碼成為現代身分驗證的基礎。授權碼流程、隱式流程和客戶端憑證流程都會傳輸使用 Base64url 的 Token。
Web API 和查詢參數
許多 REST 和 GraphQL API 在查詢參數中接受 Base64 編碼的資料,用於分頁游標、篩選器或編碼的酬載。Base64url 確保這些參數能正確運作,無需額外的 URL 編碼。
實際案例——API 游標分頁:
GET /api/users?cursor=MjAyNC0wMS0xNVQxMDozMDowMFo
GitHub 的 API 就使用這種模式來對大型結果集進行分頁。
檔案名稱與檔案儲存
Base64url 字串可以作為安全的檔案名稱,因為它們不包含路徑分隔符號(/)、不會混淆檔案系統的特殊字元,也不包含在 Windows 上無效的字元(:、*、? 等)。
內容傳遞網路和快取鍵
CDN 和快取層通常使用 Base64url 編碼的值作為快取鍵。使用標準 Base64 時,/ 會在快取命名空間中建立虛假的目錄層級結構,導致鍵值模糊不清。
在標準 Base64 和 Base64url 之間轉換
在兩種變體之間進行轉換在任何語言中都很直接:
JavaScript
// Standard Base64 to URL-safe Base64
function base64ToBase64url(base64) {
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
// URL-safe Base64 to Standard Base64
function base64urlToBase64(base64url) {
let result = base64url.replace(/-/g, '+').replace(/_/g, '/');
// Restore padding
while (result.length % 4) {
result += '=';
}
return result;
}
Node.js
Node.js 自 15.7.0 版本起提供原生的 Base64url 支援:
// Encode to Base64url
const encodedUrl = Buffer.from('Hello, world!').toString('base64url');
console.log(encodedUrl);
// Output: SGVsbG8sIHdvcmxkIQ
// Decode from Base64url
const decoded = Buffer.from(encodedUrl, 'base64url').toString('utf-8');
console.log(decoded);
// Output: Hello, world!
Python
import base64
# Encode to Base64url
encoded = base64.urlsafe_b64encode(b"Hello, world!")
print(encoded.decode())
# Output: SGVsbG8sIHdvcmxkIQ==
# Decode from Base64url
decoded = base64.urlsafe_b64decode(encoded)
print(decoded.decode())
# Output: Hello, world!
何時使用標準 Base64 vs Base64url
使用標準 Base64 的情境:
- 編碼電子郵件附件(MIME 標準要求)
- 生成用於 HTML/CSS 嵌入的 Data URL
- 將資料儲存在不需要 URL 安全性的資料庫中
- 與預期標準 Base64 的舊版系統互動
使用 Base64url 的情境:
- 建立或解析 JWT Token
- 在 URL 查詢參數或路徑區段中傳遞編碼資料
- 從二進位資料生成檔案名稱
- 建立快取鍵或識別碼
- 使用 OAuth Token 或 OpenID Connect
線上試用 Base64 URL 安全編碼
使用我們的免費線上 Base64 編碼器和解碼器在標準 Base64 和 URL 安全 Base64 格式之間進行轉換。貼上您的資料,選擇您要的變體,立即獲得結果。