一次抓包引发的思考:Base64 和加密到底是什么关系?
从实际请求看“编码”与“加密”这对黄金搭档前言前几天在分析一个前端请求时发现请求体和响应体里都是一串以结尾、包含和/的长字符串。刚开始以为是简单的“加密”但深入一想这不就是我们常说的Base64吗那么问题来了为什么要对数据做 Base64它和加密有什么联系前端做这些有意义吗后端不是也能做吗这篇文章就结合真实抓包数据把 Base64 和加密之间的关系彻底讲清楚。一、场景重现一个“奇怪”的请求我用浏览器开发者工具抓到了一个 POST 请求curl https://xxx.com/api/getData \ -H Content-Type: application/x-www-form-urlencoded \ --data-raw infoR6MaIWyjIsXy%2B4YFnQ32T6Hwx%2FEUoW560NS2sYI1M37qX5CCzAbvVrgy8rJ9Z33lOrjml%2FZdhAKGtqO7I%2FcIGwikx0vLkjUaoMEyCIQAfyoEE1YHA6HAv72Mc6J5KPoIiNnST711sXRDv%2B9OkFptT4dRQ2HHpFhR6%2BSXLqfkRQA%3D响应的内容类似这样简化版b0xWIjHvQMQJVY0Uf/k9ERvhgZBmHpTGbbR0AjgUBkdBXmx1srwhev9cr2baq6V9E1Jk/Q1LRMSYAN4TPN9qlbDsy1FAqxZ1zBTr7PRaKERRKPfwflS7q6ZIPAWp78uQ1iYwxMyxlcT1ti/icw仔细观察字符串中只有字母、数字、、/、—— 这是典型的Base64 字符集。请求里的%2B、%2F、%3D是 URL 编码后的 Base64 符号→%2B/→%2F→%3D。所以这里发生的是请求参数先被加密然后 Base64 编码最后 URL 编码。后端收到后反向解码、解密。二、Base64 不是加密是“翻译官”首先要澄清一个最常见的误解Base64 不是加密它只是一种编码方式。加密需要密钥目的是让没有密钥的人看不懂原始信息。Base64不需要密钥任何人都可以解码目的是让二进制数据能在文本环境中安全传输。可以把 Base64 想象成一个“翻译官”它把二进制计算机底层的 0 和 1翻译成英文、数字和少数几个符号这样 HTTP、JSON、URL 这些“只懂文本”的协议就能无障碍处理了。三、为什么加密后一定要用 Base64因为几乎所有现代加密算法AES、RSA、SM4 等输出的都是二进制数据。而 HTTP 协议、JSON 格式、URL 参数、HTML/CSS 都是文本协议直接传输二进制会出问题二进制里的0x00可能被当成字符串结束符截断。某些控制字符如换行、制表符会破坏 JSON 或 XML 结构。在网络上传输时可能被中间节点修改或丢弃。所以标准做法是原始数据 → 加密输出二进制 → Base64 编码输出文本 → 传输接收方再反向操作Base64 文本 → 解码还原二进制 → 解密 → 原始数据这就是你在抓包里看到的那段 Base64 字符串的来源。四、真实例子请求参数和 JWT Token4.1 请求体中的info请求里的info...经过 URL 解码后就是一个完整的 Base64 字符串。这很可能是前端把搜索条件、用户输入等敏感信息先加密再 Base64后塞进表单里的。4.2 请求头里的token/itsm_token再看请求头还有一个以eyJ开头的长字符串tokeneyJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6Imh1YW5nemhpaGFvMDIiLCJleHAiOjE3ODAzOTA1MTd9.uyXMTsQw6W-QK...这是JWTJSON Web Token它的结构是HeaderJSON 对象 → Base64PayloadJSON 对象 → Base64Signature签名二进制 → Base64然后把三段用.拼接。所以 JWT 本身也是一个 Base64 编码的产物目的是让令牌可以安全地放在 HTTP 头、URL 参数或 Cookie 中。五、前端做 Base64 到底有没有意义很多人会问前端做 Base64 不是多此一举吗后端做完加密和编码再给我不行吗实际上大部分场景下后端确实已经做了整套工作。前端只是把收到的 Base64 字符串解码然后交给解密函数处理。没有前端这一步解码后端传来的数据就没法用。也有纯前端发起的操作比如图片转 Base64 嵌入 CSS减少 HTTP 请求。小文件转 Base64 传给后端避免用multipart/form-data。这些都不涉及安全只是格式转换。六、那加密安全吗密钥会暴露吗你可能会担心前端既然能解码和解密那密钥不就暴露在代码里了吗这是一个非常关键的问题答案是真正的安全方案中前端根本不解密。正确的设计是这样的场景前端做的事情密钥在哪里登录 / 提交敏感信息用公钥加密如 RSA 公钥然后 Base64 编码发送公钥暴露无所谓私钥在后端接收加密数据只负责存储和转发 Base64 字符串不进行解密解密在后端完成JWT 验证只能解码看 PayloadBase64 解码无法验证签名验证签名的密钥在后端也就是说前端代码里不会藏着解密用的对称密钥。真正的解密工作要么在服务端要么在用户自己可控的本地环境比如端到端加密的聊天软件密钥由用户密码生成不写在代码里。七、总结一张流程图┌─────────────┐ 加密 ┌─────────────┐ Base64 ┌─────────────┐ │ 原始数据 │ ──────────→ │ 二进制密文 │ ─────────→ │ Base64文本 │ └─────────────┘ └─────────────┘ └─────────────┘ │ HTTP/JSON/URL ↓ ┌─────────────┐ 解密 ┌─────────────┐ Base64 ┌─────────────┐ │ 原始数据 │ ←────────── │ 二进制密文 │ ←───────── │ Base64文本 │ └─────────────┘ └─────────────┘ 解码 └─────────────┘加密保证数据安全输出二进制。Base64保证二进制能在文本协议中通行。两者不是互斥的而是配合使用的关系。八、最后回到最初的问题前端为什么要做 Base64因为无论是加密后的数据还是图片、文件只要是二进制要放进 JSON/HTTP/CSS 里就必须先变成文本。Base64 就是那个最通用的“翻译器”。而加密的真正安全性从来不是靠藏住 Base64 字符串而是靠密钥的正确管理——私钥永远在后端公钥可以公开对称密钥通过安全协商动态生成。希望这篇文章能帮你彻底理清 Base64 和加密的关系。下次再看到eyJ开头的 JWT 或者结尾带的长字符串你就知道它背后发生了什么。欢迎在评论区交流你的理解或疑问。