三者到底差在哪
编码、加密、哈希是三类性质完全不同的数据变换,日常讨论里经常被混为一谈。编码只是换一种表示方式,任何人拿到都能还原,Base64 与十六进制都属于这一类;加密的目标是机密性,还原必须持有密钥;哈希是单向摘要,输出定长且不可逆,只能用来比对。判断一个操作属于哪类,只需问一句:还原它需要密钥吗。
基本信息
| 编码 | 可逆、无密钥,如 Base64 / Hex / URL 编码 |
|---|---|
| 加密 | 可逆、需密钥,如 AES-GCM / RSA-OAEP |
| 哈希 | 不可逆、定长输出,如 SHA-256 |
| 密钥派生 | 把口令或共享秘密扩展成密钥,如 PBKDF2 / HKDF |
| 强度来源 | 编码无强度;加密看密钥与算法;哈希看输出长度与抗碰撞性 |
三列对照
| 维度 | 编码(Base64/Hex) | 加密(AES/RSA) | 哈希(SHA-256) |
|---|---|---|---|
| 可逆性 | 可逆,无需密钥 | 可逆,需要密钥 | 不可逆 |
| 目的 | 适配传输与存储格式 | 保密性,可附完整性 | 摘要、校验、签名输入 |
| 典型误用 | 用 Base64 保护口令 | 固定密钥、ECB 模式 | 把单轮哈希直接存口令 |
| 体积变化 | Base64 膨胀约三分之一 | 等长或附加 IV 与认证标签 | 输出定长 |
| 出错表现 | 解码失败即格式错 | 解密失败或校验标签不符 | 只能比对,无法定位差异 |
典型使用场景
- 传输二进制数据:把图片或证书塞进 JSON、URL 与邮件正文前先做 Base64
- 存储敏感字段:手机号、身份信息用 AES-GCM 加密落库,而不是编码
- 保存登录口令:用带盐的慢散列(bcrypt、Argon2id),不是哈希一轮 SHA-256
- 发布物校验:同时给出 SHA-256 摘要与来源可信的签名,防篡改防替换
- 安全评审定位问题:先分清每个环节需要的是表示转换、机密性还是完整性
判断口诀与最小验证
判断口诀与最小验证
# 能被工具直接还原且不需要密钥 → 编码
# 还原需要密钥 → 加密
# 任何方式都无法还原,只能比对 → 哈希
# 第四类:把口令扩展成密钥 → 密钥派生
echo -n 'hello' | base64 # aGVsbG8=,任何人都能解回来
echo aGVsbG8= | base64 -d # 直接还原,说明编码不含机密性
printf hello | openssl dgst -sha256 # 定长摘要,无法从输出还原明文安全评审时先确认三类操作是否用对位置:证书是 PEM 编码,私钥是需要保护的加密对象,口令应存哈希。
Base64 出现在接口响应里不等于加密:把手机号、身份信息用 Base64 打包返回,等于明文暴露。日志与埋点里出现的 Base64 字段也要按敏感数据处理。
第四类容易混淆的操作是密钥派生:它不做表示转换也不保护数据,而是把口令或共享秘密扩展成固定长度的密钥,安全性取决于计算代价、盐值与迭代次数。