AES 思想与可运行的分组/流密码

本节目标

两类对称加密:

// 运行环境:Node.js 14+
// 保存为 aj-l14.js,执行:node aj-l14.js
const crypto = require('crypto')

// 1) XOR 流密码:密钥流 = 由种子派生的伪随机字节
function xorStream(plaintext, key) {
  const keyBytes = Buffer.from(key)
  const out = Buffer.alloc(plaintext.length)
  for (let i = 0; i < plaintext.length; i++) {
    out[i] = plaintext[i] ^ keyBytes[i % keyBytes.length] // 逐字节异或
  }
  return out
}
const msg = Buffer.from('secret message')
const enc = xorStream(msg, 'mykey')
const dec = xorStream(enc, 'mykey') // 异或两次还原
console.log('密文:', enc.toString('hex'))
console.log('还原:', dec.toString()) // secret message

// 2) 直接用 Node 内置 AES(生产请用这个,别自己造轮子)
function aesDemo(plaintext, key32) {
  const iv = crypto.randomBytes(16)
  const cipher = crypto.createCipheriv('aes-256-cbc', key32, iv)
  const enc = Buffer.concat([cipher.update(plaintext), cipher.final()])
  return iv.toString('hex') + ':' + enc.toString('hex')
}
console.log('AES-256-CBC:', aesDemo(Buffer.from('hello'), crypto.randomBytes(32)))

AES 思想:每轮做"字节替换(S盒)/ 行移位 / 列混淆 / 加轮密钥",多轮叠加让明文与密钥彻底混为一体。手写完整 AES 很繁琐,但思想就是"简单变换重复多轮"。

名词解释

课后练习

  1. 为什么 XOR 流密码"密钥不能重复使用"?
    • 答案:两份密文都用同一密钥流异或,攻击者把两份密文异或就抵消了密钥流、得到两份明文异或,结合语言统计可破译。一次性密码本要求密钥真随机且只用一次。
  2. 自己手写 AES 用于生产有什么风险?
    • 答案:极易在轮数、S盒、模式(ECB 不安全)、填充、IV 处理上出错,导致可被攻破;标准库经过严格审计,应直接调用。

总结

加密这一节划清了一条铁律:理解原理 ≠ 能造轮子。你手写的 XOR 流密码足以讲清"异或两次还原"的数学美感,也能让你看穿为什么一次性密码本密钥绝不能重用;但真正上生产的 AES,必须调用经过审计的标准库——这不是偷懒,而是工程纪律。AES 的"分组 + 多轮混淆"思想本身很优雅:用几个简单变换(替换、移位、混淆、加密钥)重复十轮,就把明文和密钥搅得难解难分。我特别想强调"不要自己实现加密算法"这条红线:历史上无数系统因为"看似正确的自研加密"被轻易攻破。学加密的正确姿势是:懂它为什么安全(扩散、混淆、密钥管理),然后在代码里永远用 crypto 标准库。这节课给你的不是造加密的能力,而是"识别加密方案优劣、不踩安全坑"的判断力。