如果你曾经看到过一堆字母组成的墙 SGVsbG8gV29ybGQ= 并假设它是加密的——你不是唯一的人。Base64 是开发者工具包中最被误解的工具之一。 不是 加密。它并不能保护您的数据,只是使二进制数据在仅支持文本系统中传输时安全。
Base64是什么
Base64是一种将二进制数据编码为由64个可打印ASCII字符组成的字符串的方案:A-Z、a-z、0-9。 +,并且 /名称源自该字符集大小——64个符号,每个代表6位数据。
每三个字节的输入(共24位)映射到四个Base64字符(4×6位=24位)。如果输入长度不能被3整除, = 填充字符用于补充最后一组数据。这就是为什么Base64字符串末尾经常会看到一个或两个等号(=)。
存在的原因 (保留原文中的标点符号和格式,如逗号、句号等)
一些通道是专门为文本设计的。旧的电子邮件协议(SMTP)、HTTP头部、JSON payload和HTML属性都对可以携带而不被误解的字节有限制。通过这些通道传输原始二进制文件可能会受到损害——空字节被移除,换行符转换为其他形式,控制字符引发意外行为。
Base64跳过了所有这些问题。通过将二进制数据转换为一个可预测的可打印字符集,你可以在CSS 数据 URI 中安全地嵌入图片、附加文件到电子邮件、将令牌放置在 HTTP 头部中,并包含二进制数据 payload 在 JSON 内。代价:编码后的数据比原始数据大约是 33% 倍。
编码原理(简短版)
取字符串 Man在ASCII字节中: 77 97 110在二进制中: 01001101 01100001 01101110将数据分组为6位小组: 010011 010110 000101 101110将每个映射到Base64字母表: T W F u → TWFu.
剩余字节出现后,补零会在数据中产生。每个剩余字节将产生两个字符的Base64编码加密。 ==两个字节剩余产生三个汉字加上 =.
Base64 不是安全的。
这需要重复说明。Base64 可以通过任何拥有解码器的人进行反向操作——不需密钥,也不需密码。将其用于在客户端代码中“隐藏”密码、令牌或敏感数据提供零保护。攻击者知道 Base64 的外观。末尾的 = 这是一个抽奖活动。
如果需要保护数据在静态存储时,请使用适当的加密(AES-256)。如果需要保护数据在传输过程中,请使用TLS。Base64仅是一种运输方便措施,不是安全层。
Base64何时使用
- 数据 URI 嵌入图片直接在HTML或CSS中:
```markdown
插入图片直接在HTML或CSS中:
```
src="data:image/png;base64,iVBOR..." - 基本身份验证头信息 HTTP 基本认证编码
username:password在Base64编码中Authorization标题(仍需使用HTTPS进行实际安全性) - JSON Web Token(JWT) JSON Web Token使用Base64URL对头部和载荷部分进行编码。
- 二进制JSON/XML负载 当API或消息格式仅使用文本时
- 电子邮件附件 — 使用 Base64 对二进制文件部分进行 MIME 编码。
用户浏览器中的快速编码和解码, Base64编码器/解码器 IO Tools 处理标准版本和URL安全版本,无需安装任何软件。
实践中的编码与解码
Python
import base64
# Encode
encoded = base64.b64encode(b"Hello, World!")
print(encoded) # b'SGVsbG8sIFdvcmxkIQ=='
# Decode
decoded = base64.b64decode(b"SGVsbG8sIFdvcmxkIQ==")
print(decoded) # b'Hello, World!'
Bash
# Encode
echo -n "Hello, World!" | base64
# SGVsbG8sIFdvcmxkIQ==
# Decode
echo "SGVsbG8sIFdvcmxkIQ==" | base64 --decode
# Hello, World!
JavaScript(浏览器与Node.js) --- *(Note: The original text was a single phrase with no additional context or punctuation. I preserved the exact formatting and capitalization as-is.)*
// Encode (browser)
const encoded = btoa("Hello, World!");
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==
// Decode (browser)
const decoded = atob("SGVsbG8sIFdvcmxkIQ==");
console.log(decoded); // Hello, World!
// Node.js
const enc = Buffer.from("Hello, World!").toString("base64");
const dec = Buffer.from(enc, "base64").toString("utf8");
笔记: btoa 且 atob 仅在浏览器中处理拉丁-1字符。对于Unicode字符串,首先将其转换为字节表示形式后再进行操作。 TextEncoder.
标准与URL安全的Base64
标准的Base64使用 + 且 / — 两个在URL和查询字符串中具有特殊含义的字符。URL安全的Base64会替换它们以避免编码问题:
| 财产 | Base64编码标准 | 基于 URL 的Base64 |
|---|---|---|
| 字符集 | A-Z,a-z,0-9。 +, / | A-Z,a-z,0-9。 -, _ |
| 填充 | = 必填 | = (常省略) |
| URL安全的? | 不—— + 且 / 必须进行百分编码。 | 是的——安全用于 URL 和文件名 |
| 常用 | 电子邮件、MIME编码及通用编码 | JWT、OAuth令牌和URL参数 |
在Python中,使用 base64.urlsafe_b64encode() 为URL安全输出。JWT具体地去掉了尾随的 = 填充(这也是可以的,因为解码器可以从字符串长度推断出来)。
实用建议
Base64用于解决一个明确且特定的问题:通过仅文本通道传输二进制数据而不引起损坏。它做得很好。它并不对数据进行保护、压缩或验证。当您需要对数据进行Base64编码和解码——无论是图像、令牌还是二进制流时,现在您已经清楚知道是什么以及为什么。选择适合的工具来完成特定任务,并在安全目标实际上是实现保密性时才使用加密。
