Base64 URL-safe

编码和解码 URL 安全的 Base64(Base64url)

纯文本

Base64

本地运行 · 粘贴密钥安全无忧
Base64输出...

什么是 Base64url 编码?

Base64url 是 Base64 编码的一种变体,专为在 URL、文件名及其他标准 Base64 字符 + 和 / 会引发问题的场景中使用而设计。Base64url 在 RFC 4648 第 5 节中定义,将 + 替换为 -(连字符),将 / 替换为 _(下划线),并省略末尾的 = 填充字符。其结果是一个可直接嵌入 URL 查询参数、文件名或 HTTP 标头的字符串,无需额外的百分号编码。

标准 Base64(RFC 4648 第 4 节)使用 64 个字符:A-Z、a-z、0-9、+ 和 /。其中 + 和 / 在 URL 中是保留字符:在查询字符串(application/x-www-form-urlencoded)中,+ 被解释为空格;/ 则是路径分隔符。因此,在 URL 中使用标准 Base64 需要对这些字符进行百分号编码(%2B、%2F),这不仅增加了字符串长度,还降低了可读性。Base64url 从根本上解决了这一问题,从一开始就使用 URL 安全字符。

Base64url 最广泛的应用场景是 JSON Web Token(JWT)。JWT 的三个段——标头、载荷和签名——均采用 Base64url 编码。OAuth 2.0 PKCE 的 code_verifier、WebAuthn 挑战值以及众多 API 令牌方案也依赖 Base64url。对于任何涉及身份认证、授权或加密数据交换的开发者而言,理解此编码方式至关重要。

为何使用此 Base64url 工具?

直接在浏览器中完成 Base64url 与文本或二进制数据之间的转换。支持编码与解码两个方向,自动处理填充符和字符替换。无论您是在调试 JWT 令牌、生成 PKCE 代码质询,还是为密码重置链接创建 URL 安全标识符,本工具均在浏览器本地完成处理,零延迟、无需任何服务器往返。您在此输入的任何数据都不会离开您的设备。

即时转换
输出随输入实时更新。将文本编码为 Base64url,或将 Base64url 解码回文本,零延迟——无需提交表单或刷新页面。
🔗
URL 安全输出
输出仅包含在 URL、文件名和 HTTP 标头中安全使用的字符:A-Z、a-z、0-9、连字符和下划线。无需百分号编码。
🔒
隐私优先处理
所有编码和解码均在浏览器本地运行。您在此粘贴的 JWT 令牌、OAuth 密钥和 API 密钥永远不会传输到任何服务器。
🏛️
符合标准规范
严格实现 RFC 4648 第 5 节:- 和 _ 替换 + 和 /,省略填充符。与 JWT 库、OAuth 2.0 PKCE 和 WebAuthn 实现完全兼容。

Base64url 使用场景

JWT 令牌解析
解码 JWT 各段(标头、载荷)以检查声明、过期时间和签名算法,无需引入 JWT 库或验证签名。
OAuth 2.0 PKCE 流程
生成并验证 PKCE 的 code_verifier 和 code_challenge 值。code_challenge_method S256 要求对 code_verifier 进行 SHA-256 哈希后再做 Base64url 编码。
WebAuthn / FIDO2 集成
WebAuthn 的挑战值、凭证 ID 和认证数据在浏览器与依赖方服务器之间以 Base64url 字符串传输。解码它们以调试注册和认证流程。
API 令牌生成
将随机字节编码为 URL 安全令牌,用于密码重置链接、邮件验证和会话标识符。Base64url 生成紧凑的字符串,无需转义即可直接用于 URL。
DevOps 与 CI/CD 流水线
将二进制配置值(证书、密钥)以 Base64url 字符串形式存储在环境变量或 YAML 文件中。与标准 Base64 不同,输出不含会与 Shell 扩展或 YAML 语法冲突的字符。
数据工程
将二进制标识符、哈希值或校验和编码为 Base64url,用于文件名、数据库键或 CSV 列中——避免 + 和 / 字符破坏解析或需要转义。

标准 Base64 与 Base64url 的区别

Base64url 与标准 Base64 仅有三处不同。编码算法完全相同——只有字符集和填充行为有所变化:

特性标准(RFC 4648 §4)Base64url(RFC 4648 §5)
Index 62+-
Index 63/_
Padding= (required)Omitted

这三处差异意味着标准 Base64 与 Base64url 之间的转换极为简单:将 + 替换为 -,/ 替换为 _,去除末尾的 = 字符。反向操作则是:将 - 替换为 +,_ 替换为 /,并补充填充符使长度为 4 的倍数。大多数语言原生支持 Base64url,无需手动转换。两种转换均完全可逆且无损,能精确保留原始字节序列。RFC 4648 规范明确定义了两种编码变体,保证了不同实现之间的互操作性。在实际开发中,大多数现代编程语言已原生支持 Base64url,无需手动转换。

编码对比表

下表展示了相同输入在标准 Base64 和 Base64url 下的编码结果。注意 URL 安全变体中填充字符(=)被去除,+ 和 / 被替换为 - 和 _:

输入标准 Base64Base64url(无填充)
HelloSGVsbG8=SGVsbG8
AQQ==QQ
1+1=2MSsxPTI=MSsxPTI
subject?ref=1c3ViamVjdD9yZWY9MQ==c3ViamVjdD9yZWY9MQ
👍 (thumbs up)8J+RjQ==8J-RjQ

代码示例

以下展示如何在常用编程语言中对 Base64url 字符串进行编码和解码。每个示例的输出均可安全用于 URL、文件名和 HTTP 标头:

JavaScript (browser)
// Encode to Base64url
function toBase64url(str) {
  return btoa(unescape(encodeURIComponent(str)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '')
}
toBase64url('Hello!') // → "SGVsbG8h"

// Decode from Base64url
function fromBase64url(b64url) {
  const b64 = b64url.replace(/-/g, '+').replace(/_/g, '/')
  const pad = (4 - b64.length % 4) % 4
  return decodeURIComponent(escape(atob(b64 + '='.repeat(pad))))
}
fromBase64url('SGVsbG8h') // → "Hello!"
Node.js
// Native base64url support since Node 15.7
const encoded = Buffer.from('Hello!').toString('base64url')
// → "SGVsbG8h"

const decoded = Buffer.from('SGVsbG8h', 'base64url').toString()
// → "Hello!"

// Decode a JWT payload
const jwt = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0...'
const payload = JSON.parse(Buffer.from(jwt.split('.')[1], 'base64url').toString())
// → { sub: "1234567890" }
Python
import base64

# Encode to Base64url (no padding)
encoded = base64.urlsafe_b64encode(b'Hello!').rstrip(b'=').decode()
# → "SGVsbG8h"

# Decode from Base64url (re-add padding)
def b64url_decode(s: str) -> bytes:
    s += '=' * (4 - len(s) % 4)  # restore padding
    return base64.urlsafe_b64decode(s)

b64url_decode('SGVsbG8h')  # → b'Hello!'
Go
package main

import (
    "encoding/base64"
    "fmt"
)

func main() {
    // Encode to Base64url (no padding)
    encoded := base64.RawURLEncoding.EncodeToString([]byte("Hello!"))
    fmt.Println(encoded) // → "SGVsbG8h"

    // Decode from Base64url
    decoded, _ := base64.RawURLEncoding.DecodeString("SGVsbG8h")
    fmt.Println(string(decoded)) // → "Hello!"
}

常见问题

Base64 和 Base64url 有什么区别?
Base64url 将标准 Base64 字符集中的 + 替换为 -,/ 替换为 _,并省略末尾的 = 填充字符。这使输出可安全用于 URL、查询参数、文件名和 HTTP 标头,无需额外编码。底层算法(将字节分为 6 位组并映射到 ASCII 字符)完全相同。实际上,Base64url 字符串可以直接出现在 URL 和 HTTP 标头中而无需任何修改,而标准 Base64 字符串在这些场景中需要百分号编码(+ 编码为 %2B,/ 编码为 %2F)。这使 Base64url 成为嵌入 URL 的令牌和标识符的首选编码方式。
为什么 JWT 令牌使用 Base64url 而非标准 Base64?
JWT 经常通过 URL 查询参数和 HTTP Authorization 标头传输。标准 Base64 中的 + 和 / 在 URL 中需要进行百分号编码,增加长度并破坏简单的字符串比较。JWT 规范(RFC 7519)强制要求使用无填充的 Base64url,以确保令牌默认紧凑且 URL 安全。
如何将标准 Base64 转换为 Base64url?
将所有 + 替换为 -,/ 替换为 _,并删除末尾的所有 = 字符。在 JavaScript 中:base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')。在 Python 中:base64.urlsafe_b64encode(data).rstrip(b'=')。大多数现代语言也提供专用的 Base64url 编码函数。当需要将生成标准 Base64 的旧版库与期望 Base64url 的现代系统(如 JWT 验证器、OAuth 2.0 服务器和 WebAuthn 依赖方)集成时,这种转换尤为常见。
Base64url 编码是否可逆?
是的,Base64url 完全可逆。解码时,将 - 替换为 +,_ 替换为 /,补充 = 填充符使长度为 4 的倍数,然后按标准 Base64 解码。解码输出与原始输入字节完全一致。
可以用 Base64url 加密数据吗?
不可以。Base64url 是编码方式,而非加密手段。它将二进制数据转换为文本安全格式,没有任何保密性——任何人都可以解码。如需保护数据,请先使用适当的加密算法(AES、ChaCha20)进行加密,再对密文进行 Base64url 编码以便传输。常用的加密算法包括用于对称加密的 AES-256-GCM 和用于非对称密钥封装的 RSA-OAEP。请务必先加密数据,再对密文进行 Base64url 编码以便安全传输。
为什么 Base64url 省略填充符?
填充字符(=)在解码器可以从字符串长度计算缺失字节数时毫无意义:(4 - length % 4) % 4 即可得出所需填充量。省略填充符使字符串更短,同时避免了 = 字符在 URL 中需要百分号编码的问题。RFC 4648 第 5 节明确允许 Base64url 省略填充符。
代码中如何处理带填充符的 Base64url 字符串?
部分系统生成的 Base64url 字符串保留了 = 填充符。大多数解码器能正确处理这种情况。如果您的解码器不支持,请在解码前去除末尾的 =。反之,若某个库需要填充符,可按如下方式计算并追加:const padded = str + '='.repeat((4 - str.length % 4) % 4)。由于填充数量可由字符串长度确定,此方法可靠。一个实用的工具函数:将字符串补充 = 字符,直到长度为 4 的倍数——无论字符串是否已包含填充符,该方法均适用于所有有效的 Base64url 字符串。