Base64 是我见过被误用最多的一种伪安全操作。后端同事兴高采烈地说这个 token 我用 Base64 加密过了,前端同事礼貌地点点头,然后用 1 行代码反手打开它。
这篇文章就是为了让你下次看见 Base64 加密四个字时,能立刻指出——这不是加密。
30 秒总览
- Base64 是编码,不是加密。它只是把二进制数据转成 64 个可打印字符的方案,任何看到那串字符的人都能直接还原原文。
- 1 行代码还原: Buffer.from(str, base64).toString() (Node.js),atob(str) (浏览器),完事。
- 它的真正用途是让二进制数据能塞进只接受文本的通道——比如 JSON、邮件正文、URL query string。
- 不适合用来藏密码、token、API key——你需要的是真加密 (AES、libsodium、age、GPG)。
5 个真实场景:Base64 用错的地方
场景 1:密码加密进 config 文件
db_password 等于 cm9vdC1wYXNzLXdvcmQ=
信不信?上面那串解出来就是 root-pass-word。
为什么大家栽进去:config 文件是企业仓库里最容易被扒的地方,Base64 看上去像加了密码,但任何拿到 config 文件的人都能 5 秒还原真正的密码。
正解:用 SOPS、age、Vault,或者至少用 AES-GCM 加密。Base64 这种东西顶多算打码,谈不上加密。
场景 2:JWT 把 payload 加密
eyJhbG lKxw
JWT 中间那段通常是 Base64URL。把它丢进任何在线 JWT decoder,用户 ID、过期时间、权限列表全都出来。
为什么大家栽进去:JWT 的署名让人误以为看不见等于安全。其实 payload 这部分从来就不是被加密的,JWT 的合约里写得很清楚——只签名,不加密。如果你要加密 payload,请走 JWE。
场景 3:API 文档里加密你的 API key
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
解出来是 admin:password。
为什么大家栽进去:教程里 Authorization: Basic … 一抓一大把,新人直接抄过去,不知道那个 Basic 后面的串是 username:password 明文,只是 Base64 编码了一下。
场景 4:URL 里隐藏敏感 ID
/users/details 等于 token=MTIzNDU2Nzg5MDEyMzQ1Ng==
把内部 ID 用 Base64 包装一下塞进 URL,以为没人猜得到对应的数据库主键。
为什么大家栽进去:这属于 obscurity through encoding。Base64 字符串长得像哈希/密文,但 ID 一般是递增数字,加 Base64 也只是增加猜测成本,不增加安全性。需要猜 ID 的人用 1-2-3 顺序遍历 Base64 输出就完事。
场景 5:Slack 邮件里贴加密的代码片段
有人贴:把这段贴到生产环境前先解密,密钥我已经 base64 过了 收件人:这啥 发件人:我,原文就是 secret_api_key_here_in_plain
我以失败的项目经验起誓这个场景真实存在。
为什么大家栽进去:以为 Base64 不会被搜索/复制/截屏 OCR 抓。其实会——Base64 字符串长得特别,反而容易被自动化的流量审计工具盯上。
4 个 Base64 的反直觉事实
事实 1:Base64 字符串比原文长 33%
编码后体积会增大。3 个字节变成 4 个 Base64 字符,所以 aGVsbG8= 比 hello 长。如果你要加密还嫌字符串长度变长,说明你选错工具了。
事实 2:Base64 不能算哈希
哈希是单向(理论上不可逆),Base64 是双向(完全可逆)。两者目的根本不一样。有人想用 Base64 哈希密码然后存进数据库,等于没哈希,任何 attacker 直接解出来用。
事实 3:Base64 不是压缩
它只是字符集替换,不减小数据量。aGVsbG8= 的存储长度一定 ≥ hello 的字节数 + padding。
事实 4:浏览器 btoa 只支持 Latin-1
直接 btoa 你好 会报 InvalidCharacterError,因为 btoa 只能编码 0-255 范围。这就是为什么我们的 Text Encoder 工具走 TextEncoder().encode() 再 btoa 再 TextDecoder().decode() 的链,UTF-8 安全。
推荐做法
- 想保护密码 / token / API key——用真加密。AES-256-GCM、libsodium (crypto_secretbox_easy)、age、GPG,任选一个,千万别靠 Base64。
- 想塞二进制进 JSON / URL——用 Base64,这是它本职。我们 Text Encoder 工具的 Base64 tab 默认走 UTF-8 安全链,可解码 aGVsbG8= 直接看 hello。
- 想做 URL 安全的二进制传输——用 Base64URL (-_ 替代 +/,去掉填充),与 JWT 配套。
- 想把图片嵌入 HTML/CSS——用 data:image/…;base64,…,代价是 HTML 体积 +33%,且不能被 CDN 缓存,慎用。
- 教新人 Base64 时——强调这是搬家车,不是保险箱。搬家车把家具从 A 楼搬到 B 楼,任何搬家公司都能看到家具;保险箱 (Fort Knox) 才是真保密。
Base64 本质是字符编码方案 (RFC 4648),跟你把 hello 写 مرحبا、再写回 hello 一样——纯搬运,没有安全语义。需要安全语义,请找真正的加密原语。
试试我们的 Text Encoder 工具,切到 Base64 tab,粘贴任何字符串立刻编码/解码——1 秒看懂编码与加密的区别。如果你想进一步对比哈希 (HMAC、SHA-256),看我们的 crypto-tools。