对称加密算法:DES、3DES、AES 的那些事儿

对称加密,说白了就是加密和解密用同一把钥匙。你在网上买东西、发文件,背后几乎都有它撑腰。我这些年调过的加密模块少说也有几十个,踩过的坑能写满一本笔记。咱们先聊聊这三个老熟人——DES、3DES、AES。

DES:曾经的王者,现在的教科书案例

DES(Data Encryption Standard)诞生于上世纪70年代,是美国政府认证的加密标准。那时候计算机性能有限,56位的密钥长度被认为是安全的。

嗯,这里要注意,56位密钥在今天来看,就是一把纸锁。我在2010年参与过一个遗留系统的改造,对方还在用DES加密身份证号。我用一台普通笔记本跑了个彩虹表,不到半小时就破解了。客户当场脸色都变了。

DES 核心参数表
参数项 取值 说明
密钥长度 56位 实际密钥含8位校验位,有效位56
分组大小 64位 每次加密一个数据块
轮数 16轮 Feistel网络结构
工作模式 ECB、CBC、CFB、OFB等 ECB不安全,建议避开
⚠️ 重要提醒:DES已在2016年被NIST正式撤销。如果你的系统里还有DES,赶紧换。我曾经在金融审计中看到不少历史库还挂着DES,那是真·定时炸弹。

3DES:是补丁,不是未来

3DES(Triple DES)为了解决DES密钥太短的问题,简单粗暴地把DES跑了三遍。你可以理解成:用 K1 加密 → 用 K2 解密 → 用 K3 加密。

为什么不是 E(K3, E(K2, E(K1, plain)))?说白了,3DES用的 Encrypt-Decrypt-Encrypt (EDE) 序列,是为了兼容老设备。如果 K1=K2=K3,3DES就退化成了DES。我在项目中遇到过这种配置,对方还振振有词说"兼容性好"。兼容性是好,安全性和纸糊的没区别。

3DES 密钥选项
选项 密钥总长 有效密钥 安全级别
3TDEA(三密钥) 168位 112位 高
2TDEA(两密钥) 112位 80位 中
💡 实用建议:3DES的计算速度大约只有AES的1/3到1/5。如果你在嵌入式设备上做加密,用3DES会吃大亏。我之前调过一个POS机项目,用3DES加密交易报文,处理速度跟不上刷卡频率,差点出问题。

AES:如今的顶梁柱

AES (Advanced Encryption Standard) 是2001年由NIST正式发布的。它赢在结构设计上——用了Substitution-Permutation Network(SPN),而不是DES的Feistel结构。理论上,AES在硬件实现和软件效率上都碾压DES和3DES。

AES支持三种密钥长度,对应不同的轮数。你想想看,128位密钥就已经是2的128次方量级了,目前地球上所有计算机加起来,暴力破解也需要几十亿年。我经常跟项目组说一句话:别自己发明加密算法,用AES就够了。

AES 参数对比
密钥长度 轮数 分组大小 实际使用场景
AES-128 10轮 128位 一般商业应用,性价比最高
AES-192 12轮 128位 政府级应用
AES-256 14轮 128位 高强度安全,如金融、军工
🏆 选择建议:
  • 日常项目用 AES-128,均衡性和效率最好
  • 合规要求严(如GDPR、PCI-DSS)用 AES-256
  • 永远不要用 DES
  • 3DES 只用来兼容老旧系统,新系统一律上 AES

核心差异一图看懂

下面这张图是我自己梳理出来的。三个算法的关系、演进路径、选型依据,都在里面。记不住表没关系,把这张图印在脑子里,面试、干活都够用。

对称加密算法对比与选型决策图 已淘汰 过渡方案 当前主流 DES 密钥: 56位 分组: 64位 3DES 密钥: 112/168位 分组: 64位 AES 密钥: 128/192/256 分组: 128位 选型决策逻辑 全新系统? → 直接用 AES-128 或 AES-256 旧系统升级? → 3DES 做过渡,迁移到 AES 合规要求高? → 必须 AES-256 ⚠️ 配置陷阱提醒 • 使用 AES 时不要忘记指定工作模式(CBC/GCM)和填充方式(PKCS7/NoPadding) • 密钥生成必须用安全的随机数生成器(如 os.urandom),别自己写伪随机

代码示例:用 Python 调一下 AES

光说不练假把式。我习惯用 pycryptodome 库来调 AES,代码量小,逻辑清晰。你看看下面这段,加密一个字符串需要几步。

from Crypto.Cipher import AES
import base64

# 密钥和 IV(初始化向量)
key = b'1234567890abcdef'  # 16字节,对应AES-128
iv  = b'0102030405060708'  # 16字节,CBC模式必须

# 创建加密器
cipher = AES.new(key, AES.MODE_CBC, iv)

# 待加密数据:需要对齐16字节(PKCS7填充)
plaintext = b'Hello, AES!'
# 补位计算
pad_len = 16 - len(plaintext) % 16
plaintext_padded = plaintext + bytes([pad_len] * pad_len)

# 执行加密
ciphertext = cipher.encrypt(plaintext_padded)

# 输出Base64
print(base64.b64encode(ciphertext).decode())

运行结果类似 rUqD3nV5tLby7OxK...gw== 这样一串。你可以用同样的 key 和 IV 在 openssl 里验证,保证一致。

🛠️ 实战提醒:IV 必须是随机的,每次加密用不同的 IV。我见过一个后端同事把 IV 写死在代码里,结果相同明文加密总是得到相同密文——那还要加密干嘛?IV 的作用就是让相同的明文每次产生不同的密文,防重放攻击。

总结一下重点

  • 对称加密:加密解密同一把钥匙,速度快,适合大批量数据
  • DES:56位密钥,已不推荐任何场景使用
  • 3DES:112/168位,处理速度慢,仅作为过渡方案
  • AES:128/192/256位,主流选择,NIST推荐
  • 工作模式:ECB不安全,优先选 CBC 或 GCM
  • 密钥管理:用安全的随机数生成器,不要硬编码 key 和 IV