对称加密 AES / DES
本节目标
- 理解「对称加密」:加密和解密用同一把密钥
- 用 Node 跑通 AES(CBC/ECB)的可运行示例
- 搞懂「iv(偏移量)」「mode(模式)」「padding(填充)」
对称加密 = 一把钥匙开一把锁。前端常用 AES(先进、推荐)或老旧的 DES(已不安全)。复现 AES 时,必须同时拿到:算法/模式、密钥、iv、填充方式,缺一不可。
// 运行环境:Node.js 18+(无需依赖,用内置 crypto)
// 运行:node jsr-l8.cjs
const crypto = require('crypto')
function aesEncrypt(plain, key, iv) {
// AES-128-CBC:密钥 16 字节,iv 16 字节,PKCS7 填充(Node 默认)
const cipher = crypto.createCipheriv('aes-128-cbc', Buffer.from(key), Buffer.from(iv))
return Buffer.concat([cipher.update(plain, 'utf8'), cipher.final()]).toString('base64')
}
function aesDecrypt(b64, key, iv) {
const decipher = crypto.createDecipheriv('aes-128-cbc', Buffer.from(key), Buffer.from(iv))
return Buffer.concat([decipher.update(Buffer.from(b64, 'base64')), decipher.final()]).toString('utf8')
}
const key = '1234567890abcdef' // 16 字节
const iv = 'abcdef1234567890' // 16 字节
const enc = aesEncrypt('你好世界', key, iv)
console.log('密文:', enc)
console.log('明文:', aesDecrypt(enc, key, iv)) // 你好世界逆向要点:在 JS 里搜 createCipheriv / aes / CBC,找到 key、iv 的来源。它们可能硬编码、可能来自接口、也可能藏在闭包。四个要素必须对齐,否则解密出来是乱码。
名词解释
对称加密(Symmetric Encryption):加密和解密用「同一把密钥」。优点快,缺点是要安全地把密钥给对方。AES 是目前标准(DES 因密钥太短已淘汰)。逆向里前端 JS 里的对称密钥通常是「公开的」(在代码里),所以对称加密在前端主要防「看得懂」而非「防复现」。
IV(初始化向量)/ 模式 / 填充:IV 是「让同一明文每次密文不同」的随机量(CBC 模式必须);模式(ECB/CBC/...) 决定怎么分组;填充解决「明文不是块整数倍」的问题。复现 AES 时这三者必须和前端完全一致,否则解密失败。它们是 AES 的「四个拼图块」。
课后练习
练习 1:AES 的 key 和 iv 一般各多少字节(AES-128)?
答案:AES-128 的 key 是 16 字节(128 位);CBC 模式的 iv 也是 16 字节(一个分组大小)。key 长度错会直接报错,iv 错会解出乱码。
练习 2:ECB 模式和 CBC 模式哪个更不安全?为什么?
答案:ECB 更不安全。ECB 不依赖 IV、相同明文块加密出相同密文块,容易从密文看出结构(如图片轮廓)。CBC 用 iv 把块串起来,相同明文不同密文,所以更抗分析。逆向看到
ecb要警惕它「没藏住结构」。
总结
AES 是前端加密的「主力」,也是逆向复现里最容易「差一个参数就全错」的类型。我的观点:复现 AES 别急着写代码,先像查字典一样把四个要素(算法+模式、key、iv、padding)从 JS 里一个个抠出来列在纸上,再动手。新手 90% 的失败是「iv 没找全」或「padding 假设错了」。另外要认清一个现实:前端 JS 里的 AES 密钥基本是公开的,它防的是「人肉读代码」,不是「防你复现」——所以这类加密在逆向里通常能 100% 还原,只是要细心。把四个要素当 checklist,一项项打勾,稳。