文章
在本地私密地编码和解码数据
开发者每天把令牌、负载和凭据粘贴到编码与解码页面。最方便的那些运行在服务器上,这意味着为了一件本不需要如此的任务,你的数据离开了设备。这四个工具完全在浏览器中运行,所以数据留在你手中。
Base64:看起来乱码,其实并不保密
Base64 是一种编码,不是加密。它把二进制数据转成文本,使其能经受复制粘贴,或穿过只处理简单字符的系统。任何看到 Base64 字符串的人都能一步把它解回原样,因此一段包含 API 密钥、私有证书或邮件正文的字符串,对持有者而言完全可读。风险在于这个值常藏在配置文件、data URL 或认证头里,看上去晦涩,从而诱使人把它粘贴到网上找到的第一个解码器。那个解码器拿到的是原始的秘密。一个在本地解码 Base64 的工具会向你展示原始字节,而这个值从不抵达任何服务器。

URL 编码:查询字符串携带的东西比你以为的多
百分号编码让你能把空格、重音符号和保留字符安全地放进 URL。你编码或解码的文本往往是来自某个应用的真实查询字符串,它们携带会话标识符、搜索词、电子邮件地址、跳转目标,有时还有签名参数。把完整的 URL 粘贴到远程编码器,会把这一切一次性交给第三方,而查询字符串正是那种会落进服务器日志的值。在浏览器中编码和解码,意味着 URL 在你自己设备的内存中处理,在你操作期间从不被传输。
JWT:负载是被签名的,而非被隐藏
一个 JSON Web Token 由用点连接的三段 Base64url 组成:头部、负载和签名。签名证明令牌未被篡改,却完全不会隐藏负载,负载会解码成可读的 JSON,含有用户标识符、角色、过期时间,以及签发者添加的任何自定义声明。有效的令牌同时也是一份活的凭据:在过期之前,任何持有它的人都能以该用户的身份行事。把可用的令牌粘贴到在线解码器,就把一份有效凭据送往了你无法掌控的服务器。一个在你浏览器中解析令牌的解码器,会展示同样的头部和负载,而这个令牌从不离开页面。

哈希:输入比摘要更重要
哈希函数把任意输入变成固定长度的摘要,而你无法把摘要逆推回输入。这一性质让哈希适合用来校验文件完整性,或在不保存原件的情况下比较数值。陷阱在输入这一端:要计算一个密码、一份文档或一个配置秘密的哈希,你必须把真实的值交给工具。如果这个工具运行在服务器上,即便返回的只是无害的摘要,敏感的输入也已经送到了那里。在本地计算哈希会把输入留在你的设备上,于是你得到所需的摘要,却不暴露你正在哈希的东西。
Base64 编码:字节映射与填充
Base64 通过将三个输入字节(24 位)分组为四个 6 位值,将 8 位字节转换为 6 位字符。每个 6 位值映射到 Base64 字母表中的一个字符(A-Z、a-z、0-9、+、/)。由于该过程要求输入可被 24 位整除,较短的输入需要填充:剩余一个字节产生两个填充字符(==),剩余两个字节产生一个(=)。用于 JSON Web Tokens(JWTs)的 Base64url 变体将 + 替换为 -,将 / 替换为 _,使字符串对 URL 安全,并完全去掉 = 填充,因为填充字符可能在严格的 URI 解析器中引发错误。在调试令牌处理时,识别这种区别非常重要:看起来格式错误的 JWT 可能只是经过 Base64url 编码,而非标准 Base64。
JWT 签名:HS256、RS256 与算法混淆
JSON Web Token 的安全性完全依赖于其签名,即第三个以点分隔的部分。使用 HS256(HMAC-SHA256)时,服务器使用密钥对经过 Base64url 编码的头部和载荷进行签名。SHA-256 哈希函数提供抗碰撞性:在不知道密钥的情况下,计算上不可能生成一个修改后的载荷使其哈希到相同的签名。使用 RS256 时,服务器使用 RSA 私钥签名,并使用公钥验证。当服务器库未严格强制执行预期的算法类型时,会产生一种被称为算法混淆的已知漏洞。攻击者可以将令牌头部的 alg 字段从 RS256 改为 HS256,并使用服务器的公钥作为 HMAC 密钥来签署令牌,因为公钥通常是可访问的。在浏览器中本地解码 JWT 头部可以验证实际指定的算法,而无需将活跃令牌暴露给第三方日志记录系统。
本文涉及的工具
常见问题
Base64 或 URL 编码算是一种安全手段吗?
不算。两者都是可逆的编码,为安全传输数据而设计,并非用来保护数据。任何能读到编码字符串的人都能立刻解码,无需密钥或密码。如果你需要让某个值保密,请用合适的算法加密它,并把密钥单独管理。把任何 Base64 或百分号编码的值都当作以明文写就的来对待。
我在哪里解码令牌或哈希密码,为什么会有区别?
因为敏感的部分是输入。有效的 JWT 是一份活的凭据,而你哈希的密码就是真正的秘密。基于服务器的工具在返回结果之前就已经收到那份原始输入,这意味着副本可能被记入日志,或被保存在你看不到的地方。在你浏览器中运行的工具,会在你自己设备的内存里完成同样的操作,所以令牌或密码从不被送往任何地方。