如何解码 Basic 认证请求头
- 把值粘贴到 Authorization 请求头、Basic 令牌或带凭据的 URL。以下形式都可以:
Authorization: Basic YWRtaW46czNjcjN0OnBhc3M=Proxy-Authorization: Basic …Basic YWRtaW46czNjcjN0OnBhc3M=或只有令牌https://user:password@host/path
- 字符集 保持自动检测;如果结果看起来不对,可以强制使用 UTF-8 或 ISO-8859-1。
- 查看 用户名 和 密码,可以分别复制;如果某个字符看起来可疑,检查 解码后的字节(hex)。
只解码 Basic 方案。Digest 和 NTLM 请求头是另一种格式,会被报告为其他方案。
解码器显示什么
| 输入 | 用户名 | 密码 | 说明 |
|---|---|---|---|
Basic YWRtaW46czNjcjN0OnBhc3M= | admin | s3cr3t:pass | 只在第一个冒号处分割,密码保留其中的冒号。 |
dGVzdDoxMjOj | test | 123£ | 不是有效的 UTF-8,自动检测回退到 Latin-1。 |
dGVzdDoxMjPCow== | test | 123£ | 相同的文本,UTF-8 字节。 |
https://ci-bot:p%40ss@ci.example.com/ | ci-bot | p@ss | 取自 URL,并已做百分号解码。 |
Bearer eyJhbGciOi… | 错误:这是 Bearer 令牌,附有 JWT 解码器的链接。 |
自动检测按顺序进行。纯 ASCII 在所有字符集中解码结果都一样;能构成有效 UTF-8 的字节按 UTF-8 读取;其他一律按 ISO-8859-1 读取,这是 HTTP 请求头的传统默认编码。这里的 Latin-1 指真正的 ISO-8859-1。Windows-1252 与它在 0x80–0x9F 范围内不同,€ 之类的字符就在这个范围,因此 Windows-1252 的密码可能会显示成控制字符。
对于不规范的令牌,例如缺少 = 填充或使用了 URL 安全的 - 和 _,解码器会宽松处理并给出提示,因为严格的服务器会拒绝它们。如果解码得到的文本里根本没有冒号,说明该值不是 user:password 对,工具会如实报告。
Basic 凭据会出现在哪里
- 浏览器开发者工具。 网络面板会显示每个请求的请求头,包括
Authorization。 - curl。
curl -v会打印请求,因此-u user:pass会显示为> Authorization: Basic …。 - HAR 文件和代理抓包,它们保存了每个请求的完整请求头。
- 服务器和代理配置,用写死的请求头让后端获得访问权限,例如 nginx 中的
proxy_set_header Authorization "Basic …"。 - Docker 镜像仓库凭据。
~/.docker/config.json中的auth字段是user:password的 Base64;dockerconfigjson 解码器 可以打开整个文件。 - 应用日志,当框架记录传入的请求头却没有脱敏时。
以上每一种都是只套了一层编码的明文密码,请像对待密码本身一样对待它们。Base64 不是加密 解释了为什么这种编码起不到任何保护作用。
在服务器端解码请求头
框架通常会替你完成这一步,但在脚本和测试中,一个小解析器很有用:
import base64
def parse_basic(header_value):
scheme, _, token = header_value.strip().partition(" ")
if scheme.lower() != "basic":
raise ValueError("not a Basic credential")
user, colon, password = base64.b64decode(token).decode("utf-8").partition(":")
if not colon:
raise ValueError("no colon in the decoded value")
return user, password
print(parse_basic("Basic YWRtaW46czNjcjN0OnBhc3M="))
它会输出 ('admin', 's3cr3t:pass')。方案名称不区分大小写,所以要转成小写再比较;而且一定要用 partition 或 split(":", 1),这样密码中的冒号才能保留下来。校验密码时要使用恒定时间比较,例如对编码后的字节使用 hmac.compare_digest,而不是 ==。反方向请使用 Basic Auth 请求头生成器;更多 Base64 用法见 Python 页面。
常见问题
怎么手动解码 Basic 认证令牌?
去掉 Basic 这个词和后面的空格,对剩下的部分做 Base64 解码,然后在第一个冒号处分开。在 Linux 或 macOS 上,echo 'YWRtaW46czNjcjN0OnBhc3M=' | base64 -d 会输出 admin:s3cr3t:pass。
“这是 Bearer 令牌”是什么意思?
该请求头使用的是 Bearer 方案,携带的是令牌而不是用户名和密码。Bearer 令牌通常是 JWT,可以在 JWT 解码器 中打开。
为什么解码出的密码里有奇怪的符号?
写入字节时使用的字符集很可能和读取时不同。在 字符集 中切换自动检测、UTF-8 和 ISO-8859-1,并查看 hex 字节:C2 A3 在 UTF-8 中是 £,而单独的 A3 在 Latin-1 中是 £。
我在日志里发现了 Basic 认证请求头,该怎么办?
把该密码视为已泄露,立即更换。然后堵住泄露源:配置代理、Web 服务器或日志库,对 Authorization 请求头做脱敏处理。