Basic 认证的密码是"编码"不是"加密":一眼就能还原

Basic 认证的密码是

一、它怎么工作

Basic 认证的做法是:客户端把「用户名:密码」用 Base64 编码,放进请求头 Authorization: Basic ... 里发给服务器。原文给的例子很直观——用户名 bob、密码 12345,编码后这行头就是 Authorization: Basic Ym9iOjEyMzQ1。

Base64 是一种可逆的编码方式,不是加密算法,也没有密钥。任何人拿到这串字符,用任何工具都能立刻还原出明文密码。

二、四种参数写法,差异在"谁来填密码"

写法行为适用
用户名 + 冒号 + 密码直接使用给定密码脚本调用
把账号密码写进 URL效果同上,由工具解析后发出临时测试,不推荐
只写用户名加冒号密码为空,服务端允许空密码才成功极少数特殊环境
只写用户名、不带冒号命令行交互提示输入密码手动操作,避免密码进历史记录

最后一种写法的价值不在功能,而在安全:密码不落进 shell 历史、不写进脚本、不出现在进程列表里。反过来,"写进 URL"虽然省事,但地址栏、代理日志、访问日志都可能记下明文口令,属于典型的踩坑写法。

三、真正的风险点在哪

Basic 认证本身只解决"如何把身份带给服务器",不解决"如何不让别人看到"。所以它的安全完全依赖外层协议——必须跑在 HTTPS 之上。

三个具体风险:

  • 明文链路上等于公开。HTTP 传输时,任何能抓包的位置都能直接读到账号密码。
  • 日志泄露。URL 带账号密码的写法,会把凭证写进服务器访问日志和中间代理日志。
  • 无法撤销单次泄露。Base64 一旦被截获,重放即可复用,没有一次性令牌机制。

四、什么时候用它是对的

  • 内网服务、测试环境的临时保护;
  • 已经强制 HTTPS,且凭证权限有限(只读、只访问单一接口);
  • 配合访问控制(IP 白名单)作为第二道门。

不适合的场景同样清晰:对外开放的正式接口、涉及支付或个人信息的系统、多人共用的长期凭证。这些场景应使用带过期时间的令牌或签名机制。

五、实践中的五条纪律

  1. 只走 HTTPS,永不例外。
  2. 不要在 URL 里带账号密码,改用请求头或交互输入。
  3. 脚本里的凭证放环境变量或密钥管理服务,不硬编码。
  4. 给这类凭证最小权限,能只读就不要给写。
  5. 定期轮换,并在日志里排查是否出现过明文口令。

把它当成"身份传递方式"而不是"安全机制",很多误用就不会发生。