数据加密,其实没那么玄乎
做系统开发这些年,我经常遇到一个现象:一说加密,很多人就觉得是密码学专家才能碰的领域。坦白讲,我也曾经这么想。直到有一次在项目中因为没给敏感数据做加密,被安全审计卡了整整两周……嗯,从那以后我意识到,加密基础是每个工程师的必修课。
说白了,数据加密就是把看得懂的信息(明文)通过某种规则变成看不懂的乱码(密文)。这个规则由两部分组成:算法和密钥。你想想看,如果只有算法没有密钥,那解码就太容易了——大家用的是同一个算法嘛。所以密钥才是真正的“命门”。
加密三要素:缺一不可
我习惯把这三样东西记成一个铁三角:
- 密钥 —— 加密和解密时用的“暗号”,通常是一串二进制数
- 算法 —— 数学转换的规则,比如AES、RSA这类
- 明文 / 密文 —— 加密前的原始数据 vs 加密后的乱码
重要原则: 加密算法的安全性必须依赖于密钥的保密性,而不是算法本身的保密。千万别觉得自己“魔改”了某个算法就安全——我见过太多团队自己发明加密方法,结果被攻破得惨不忍睹。
举个例子,你给朋友写一封密信,用了一本《现代汉语词典》第6版作为密钥本。你们约定好:每个词在词典的页码+行数组合起来就是密文。这里的《词典》就是算法,页码+行数就是密钥的形态,而信的内容就是明文。算法公开(大家都知道词典)没关系,只要你们约定的密钥不泄露就安全。
加密算法三大门派
市面上的加密算法,按应用场景可以分成三类。我一个个说。
对称加密
加解密用同一把密钥。效率高,适合大批量数据。
- 代表算法:AES、3DES、SM4(国密)
- 典型场景:文件加密、数据库字段加密、SSL协议中传输数据加密
- 痛点:密钥分发困难——两个人通信,怎么安全地把密钥告诉对方?
我在做API网关的时候,就用AES-256加密请求体里的敏感字段。速度快,对业务几乎无感。
非对称加密
有公钥和私钥两把钥匙。公钥可以公开分发,私钥只有自己保管。
- 代表算法:RSA、ECC、SM2(国密)
- 典型场景:数字签名、密钥交换、HTTPS握手
- 慢,但解决了密钥分发难题
个人习惯: 非对称加密我基本只用ECC,因为同样安全强度下,ECC的密钥长度更短,计算更快。RSA 2048位已经够用,但新项目我会优先选ECC。
哈希算法
严格来说不算加密,因为它不可逆。把任意长度的数据变成固定长度的摘要,而且一模一样的输入一定得到相同的输出。
- 代表算法:SHA-256、SHA-3、SM3(国密)
- 典型场景:密码存储、文件完整性校验、区块链交易摘果
- 注意:MD5、SHA-1已经不安全,别用了
我记得有一次,一个同事用MD5存用户密码,还跟我说“开源项目都这么干”。我问了他一句:“你知道MD5碰撞有多容易吗?”后来他默默改成了bcrypt加盐,其实用SHA-256加盐也行。
三大算法对比清单
| 特性 | 对称加密 | 非对称加密 | 哈希算法 |
|---|---|---|---|
| 密钥数量 | 1个 | 2个(公钥+私钥) | 无密钥 |
| 运算速度 | 快(几百MB/s) | 慢(几KB/s) | 中等 |
| 是否可逆 | 是 | 是 | 否 |
| 典型用途 | 数据加密传输/存储 | 密钥交换、数字签名 | 完整性校验、密码存储 |
| 密钥管理难度 | 高 | 低(公钥随意分发) | 不涉及 |
| 代表算法 | AES-256, SM4 | RSA-2048, ECC, SM2 | SHA-256, SM3 |
避坑指南: 千万不要对密码做“对称加密”后存数据库。即使你加了盐,只要数据库泄露,攻击者拿到密钥就能批量解密。我曾经在一个遗留项目中看到过这种做法——用AES加密密码,密钥写死在代码里。我说句不好听的,这跟把密码写在便利贴贴显示器上没区别。正确做法是加盐哈希,而且用专业的密码哈希算法(bcrypt、scrypt、Argon2)。
一张图理清加密体系
下面这张图概括了加密基础的核心脉络,我个人很喜欢用这种结构图给新来的同事讲概念——三维结构一目了然。
这张图把加密三要素和三大类算法串联起来。你可以看到:密钥+算法+明文/密文构成基础,算法又派生出三种不同用途的分类。实际工程中,三种算法往往组合使用——比如HTTPS先用非对称交换会话密钥,再用对称加密传输数据,最后用哈希校验完整性。
一个小建议: 刚接触加密的同学,别急着研究高深的数学原理。先把这三类算法的特性和适用场景搞清楚。我在带团队时,会让大家先画一个“加密选型决策树”:
- 需要可逆且高效 → 对称加密
- 需要安全传递密钥 → 非对称加密
- 只需验证完整性/不可篡改 → 哈希
动手试试:用Python感受加密过程
说这么多,不如跑两行代码。下面我用Python的cryptography库演示对称加密的完整流程。这东西我天天用,稳得很。
from cryptography.fernet import Fernet
# 1. 生成密钥(对称加密的本质就是这串随机字节)
key = Fernet.generate_key()
cipher = Fernet(key)
# 2. 加密
plaintext = b"Hello, 信封加密教程来了!"
ciphertext = cipher.encrypt(plaintext)
print("密文:", ciphertext)
# 3. 解密
decrypted = cipher.decrypt(ciphertext)
print("解密后:", decrypted.decode())
你把这个跑一遍,看到密文是一串乱码,但解密后原封不动。这就是对称加密最直观的样子。注意Fernet底层用的是AES-128,但生成密钥时就已经把一切细节封装好了。
曾经掉过的坑: 我第一次用cryptography时,把key直接打印出来了。结果同事提醒我——密钥不能以明文形式出现在日志里!从那以后我养成了习惯:密钥要么从环境变量读,要么走KMS(后面章节会聊)。另外,Fernet生成的密钥默认是base64编码的,你可以存成字符串,但一定别忘了用key.encode()还原回字节。
总结一下
加密基础不复杂,记住三要素(密钥、算法、明文/密文)和三大门派(对称、非对称、哈希)就够了。至于哪个场景选哪种,后面我们在信封加密与KMS结合时会反复用到。你对这些基础掌握得越牢,后面理解KMS的密钥分层、密钥轮换、信封加密就越轻松。