返回知识库

数据与服务 · 账号与安全

加密Encryption

加密是用密钥可逆地把明文变成密文;哈希是单向不可逆、靠重哈希比对验证(hashing ≠ encryption)。按数据要不要取回选手段:敏感字段加密、密码哈希、传输走 TLS;密钥由 KMS 托管,永远别自己造密码学。

加密可逆、哈希不可逆、翻转密文看乱码

先把三种数据保护手段在同一台工作台上跑一遍,亲眼看到加密能还原、哈希不能还原、密文被改一位就解出乱码,再读后面的规则命名。

同一段明文,三种不同变换:加密用密钥把明文变成密文(可逆,有钥就能还原);哈希把明文压成固定长度摘要(单向,不可逆,靠重哈希比对验证,不是加密); 翻转密文一位再看能不能还原(完整性)。

模式

所有密文 / 摘要均为演示字符串,不是真实密码学产物;真实系统请用受审库(AES-GCM / argon2 / TLS)。

密钥槽
共享密钥加密和解密用同一把钥 · 快 · 适合数据
密文

(空)先点「加密」。

解密结果

(空)先加密,再「用密钥解密」。

哈希摘要

(空)先点「计算哈希」;哈希没有「解密」按钮。

重哈希比对

输入密码,点「重哈希比对」。

翻转密文一位

原因 · 下一步 · 对照原因:还没有任何产物。下一步:点「加密」看明文被变成密文;再点「用密钥解密」看它能还原。对照:加密是可逆的——有密钥就能取回原文,这是它和哈希最大的区别。

提示:主操作「加密」是唯一的红色按钮;其余按 Tab 顺序可达。重点试三组对照——加密后解密看可逆、翻转密文后解密看乱码、哈希后重哈希比对看验证。

工作台暴露的五条规则

面板已经把每条规则演给你看了,这里把它们命名清楚,并补上无法直接操作的部分。

  • 加密是可逆的:有密钥就能还原。明文经密钥变换成密文,持有密钥的人可以解密还原;所以加密适合「需要取回的敏感字段」(邮箱、手机号、需要展示末四位的卡号),但不适合密码——密码不需要取回。
  • 哈希是单向的:不可逆,验证靠重哈希比对。哈希把任意输入压成固定长度摘要,没有「解密」按钮;验证密码只能把用户输入重新哈希一次,再和注册时存的摘要比。这正是「hashing ≠ encryption」——加密能解密,哈希不能。
  • 密码存慢哈希 + salt,不存加密。用 bcrypt / argon2 / scrypt 等专用慢哈希,并为每个密码生成独立 salt;这样即便存档摘要泄漏,暴试成本也被大幅抬高。把密码用对称加密存起来(哪怕密钥在 KMS)反而是错的——你不该能取回它。
  • 加密本身不保证完整性。翻转密文一位,密钥虽然正确,解出来却是乱码;生产中用 AES-GCM / ChaCha20-Poly1305 等「带认证的加密」,解密前先验认证标签,发现篡改直接拒绝,而不是返回乱码。
  • 对称快、非对称便于交换,TLS 把两者混合。对称加密(AES)用同一把钥加解密,快、适合大量数据,但双方要先安全地共享密钥;非对称(RSA / ECDH)用公钥私钥一对,不用事先共享秘密,但慢。TLS 先用非对称安全地交换一个对称「会话钥」,之后用对称加密传真实数据——两者各取所长。

什么时候用哪种:按「要不要取回」和「在哪一段」决定

先看数据要不要被还原,再看保护的是存储还是传输,而不是把所有敏感数据都丢给同一个「加密」。

  • 需要取回的敏感字段(邮箱、实名、需展示的卡号末四位)→ 用成熟对称加密(AES-GCM)加密存储,密钥由 KMS / secret manager 托管;解密权限最小化并记录访问。
  • 不需要取回的凭证(用户密码、API secret 校验值)→ 用慢哈希(argon2 / bcrypt)+ 独立 salt 存储;登录 / 校验靠重哈希比对,不要提供解密路径。
  • 传输中的数据→ 一律走 TLS / HTTPS;不用自己在应用层加密整条报文。TLS 已经用非对称换好会话钥,应用层再加密既慢又容易出错。
  • 完整性 / 不可否认(确认数据没被改、确认是谁发的)→ 用签名(HMAC 或非对称签名)。签名关心「没被改 + 是谁签的」,和「能不能读」是两回事——见 token 卡片的签名部分。
  • 不要做的:用「加密」存密码;用「哈希」保护需要还原的字段;自己拼算法 / 模式 / 随机数;把密钥写进代码、前端 bundle、日志或错误上报。

从分类到落地:最短路径

只走这几步,每步都让「用哪种保护、密钥从哪来」可验证。

  1. 把敏感字段分类:要取回的进「加密」清单,不要取回的凭证进「哈希」清单,传输交给 TLS——清单写清「哪些字段、用哪种保护」。
  2. 加密字段用受审库的 AES-GCM(带认证),密钥从 KMS / secret manager 按环境取,轮换和撤销有流程;代码里只引用密钥的标识,不写死值。
  3. 密码字段用 argon2 / bcrypt + salt,调高 cost;登录把输入重哈希再比对存档摘要,登录失败不泄露是「用户名错」还是「密码错」太多。
  4. 传输全站 HTTPS / TLS,HSTS 强制;服务端只接受 TLS,凭据(Cookie / token)标 Secure,不在 URL 里传密钥或令牌。
  5. 测试验证「真实算法 + 密钥来源 + 篡改拒绝」,而不是「看起来像密文」;密钥泄漏演练覆盖 KMS 撤销、轮换和旧密文重新加密。

同一目标「存用户登录密码」:哈希 + salt,还是可逆加密

只改一处——存的时候用哈希还是可逆加密——安全性质完全不同。这是密码学分类最该记住的一条。

正例:argon2id(password, salt) 存摘要,登录重哈希比对store = argon2id(password, salt)

存档的是单向摘要,无法被「解密」回原文;每个密码独立 salt 抵御彩虹表;慢哈希抬高暴试成本。数据库泄漏后,攻击者仍要逐条暴试,且 cost 调高后代价巨大。

反例:AES 加密密码存库,密钥放在配置 / 代码里store = AES(password, key_in_config)

密码能被还原——但服务根本不需要还原它,这是多余的权限。一旦配置或代码里的密钥泄漏(这正是常发生的),整库密码瞬间全部裸奔成明文。把「不该取回的数据」做成可逆,等于把单点风险放大成全量风险。

快速自测

同事说:用户银行卡号既要展示后四位,又要取回完整号去扣款;而登录密码只需要验证对不对。这两类该分别怎么存?

继续查证

术语的技术定义和行为以这些一手或权威资料为准。

下一步学

和本知识点经常一起出现的概念。